home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / PASSDK30.ZIP;1 / DISK1.ZIP / PAS / SUBS / MIXERS / DIALOG.C < prev    next >
Encoding:
Text File  |  1993-02-18  |  74.0 KB  |  3,519 lines

  1. ;    /*\
  2. ;    |*| $Author:   DCODY  $
  3. ;    |*| 
  4. ;    |*| $Date:   18 Feb 1993 11:48:22  $
  5. ;    |*| 
  6. ;    |*| $Header:   X:/sccs/mixers/dialog.c_v   1.18   18 Feb 1993 11:48:22   DCODY  $
  7. ;    |*| 
  8. ;    |*| $Log:   X:/sccs/mixers/dialog.c_v  $
  9.  * 
  10.  *    Rev 1.18   18 Feb 1993 11:48:22   DCODY
  11.  * dissolve to mono screens was broken.
  12.  * 
  13.  *    Rev 1.17   25 Jan 1993 14:36:04   BCRANE
  14.  * removed extraneous words[]
  15.  * 
  16.  *    Rev 1.16   20 Nov 1992 16:35:26   DCODY
  17.  * changed the dissolve screen restore to work only on exit of the dialog. Also
  18.  * corrected a couple Borland C barfs.
  19.  * 
  20.  *    Rev 1.15   12 Nov 1992 10:02:40   DCODY
  21.  * added dissolve on screen restoration. Changed some code for
  22.  * Borland compatibility.
  23.  * 
  24.  *    Rev 1.14   20 Oct 1992 15:53:30   BCRANE
  25.  * changed text on Speaker control to include SB Volume
  26.  * 
  27.  *    Rev 1.13   19 Oct 1992 11:41:18   BCRANE
  28.  * added "blank" strings for when no SB volume control on PAS+
  29.  * 
  30.  *    Rev 1.12   16 Oct 1992 10:19:30   BCRANE
  31.  * fixed error in getting the pathname
  32.  * DOS has "C:\" for the root, whereas we store only "C:", so
  33.  * building the pathname for the settings.pas file was "C:settings.pas"
  34.  * when mvsound.sys was in the root directory.
  35.  * 
  36.  *    Rev 1.11   09 Sep 1992 13:44:30   BCRANE
  37.  * changed MixerRect, RecordRect, and all mixer elements start and end x-coords
  38.  * up 1.
  39.  * 
  40.  *    Rev 1.10   04 Sep 1992 13:24:42   BCRANE
  41.  * changed bottom coordinate of MixerRect
  42.  * 
  43.  *    Rev 1.9   02 Sep 1992 10:03:04   BCRANE
  44.  * added SB volume control
  45.  * 
  46.  *    Rev 1.8   22 Jul 1992 08:21:14   BCRANE
  47.  * added #if USEMIXERGET to use either MixerGetSettings with 
  48.  * callback to "subsavecurrent" or "savecurrent".  Currently set
  49.  * to 1 to use MixerGetSettings.
  50.  * 
  51.  *    Rev 1.7   13 Jul 1992 11:57:02   BCRANE
  52.  * changed F3/SF3 to F5-F8/SF5-SF8
  53.  * now saves setting#.pas where # is 0-3
  54.  * modified F1 help to indicate this new feature 
  55.  * 
  56.  *    Rev 1.6   13 Jul 1992 09:41:56   DCODY
  57.  * GetMixerSettings now reports dead mixer settings
  58.  * 
  59.  *    Rev 1.5   10 Jul 1992 16:57:44   BCRANE
  60.  * changed INPUT to MIXER
  61.  * 
  62.  *    Rev 1.4   10 Jul 1992 16:38:52   BCRANE
  63.  * finalized (!) save and load defaults - handles input/output mixers
  64.  * last-one-active situation, as well as absolute vs. percent values
  65.  * 
  66.  *    Rev 1.3   09 Jul 1992 17:45:16   BCRANE
  67.  * added load and save current state and getdriverpath
  68.  * not fully complete
  69.  * 
  70.  *    Rev 1.2   01 Jul 1992 14:40:58   DCODY
  71.  * added OEM specific wording
  72. *    Rev 1.1   23 Jun 1992 16:44:32   DCODY
  73. * PAS2 update
  74. *    Rev 1.0   15 Jun 1992 09:41:16   BCRANE
  75. * Initial revision.
  76. ;    |*| 
  77. ;    |*| /*$Logfile:   X:/sccs/mixers/dialog.c_v  $
  78. ;    |*| 
  79. ;    |*| /*$Modtimes$
  80. ;    |*| 
  81. ;    \*/
  82.  
  83.     /*\
  84.     |*|---====< DIALOG.C  --  PAS User interface module >====----
  85.     |*|
  86.     |*| Pro Audio Spectrum Mixer User Interface program. This
  87.     |*| program provides mixer control from the command line.
  88.     |*|
  89.     |*| Media Vision, Inc. Copyright (c) 1991, All rights reserved
  90.     |*|
  91.     \*/
  92.  
  93.     /* minor revisions to allow integration with audiolnk (large model) */
  94.  
  95. #include <stdio.h>
  96. #include <stdlib.h>
  97. #include <string.h>
  98. #include <ctype.h>
  99. #include <bios.h>
  100.  
  101. #include <fcntl.h>
  102. #include <sys\types.h>
  103. #include <sys\stat.h>
  104. #include <io.h>
  105.  
  106. #include "dialog.h"
  107. #include <binary.h>
  108.  
  109. #ifndef OEM
  110. #define OEM 0
  111. #endif
  112.  
  113.     /*\
  114.     |*|----====< some prototypes >====----
  115.     \*/
  116.  
  117.         int     EqualizerLevels     ( );
  118.         int     ScrollObjectHandler ( );
  119.         int     SwitchObjectHandler ( );
  120.         int     VolumeLevels        ( );
  121.         int     VolumeButtons        ( );
  122.         int     EffectsButtons        ( );
  123.  
  124.  
  125.     /*\
  126.     |*|----====< global data >====----
  127.     \*/
  128.  
  129. #define TRUE    -1
  130. #define FALSE    0
  131.  
  132.     static char makemenull[]="";
  133.  
  134.     static char *screenlayout[] = {
  135.  
  136.         "⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø",
  137. #if OEM
  138.         "≥           Spectrum            ≥",
  139. #else
  140.         "≥Media Vision Pro AudioSpectrum ≥",
  141. #endif
  142.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ≈",
  143.         "≥ FM         ≥≥≥",
  144.         "≥ Synthesizer≥≥≥",
  145.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  146.         "≥ External   ≥≥≥",
  147.         "≥ Jack       ≥≥≥",
  148.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  149.         "≥ Internal   ≥≥≥",
  150.         "≥ Connector  ≥≥≥",
  151.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  152.         "≥ Microphone ≥≥≥",
  153.         "≥ Jack       ≥≥≥",
  154.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  155.         "≥ PC         ≥≥≥",
  156.         "≥ Speaker    ≥≥≥",
  157.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  158.         "≥ SB Digital ≥≥≥",
  159.         "≥ Audio      ≥≥≥",
  160.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  161.         "≥ Digital    ≥≥≥",
  162.         "≥ Audio      ≥≥≥",
  163.         "¿ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ"
  164.     };
  165.  
  166.     static char *screenlayoutblank[]=
  167.         {
  168.         "√ƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥                √",
  169.         "≥            ≥≥                ≥",
  170.         "≥            ≥≥                ≥"
  171.         };
  172.  
  173.     static char *screen2[] = {
  174.  
  175.         "⁄ƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒø",
  176.         "≥Volume  ≥ Volume Control ≥ ≥",
  177.         "√ƒƒƒƒƒƒ¬ƒ≈ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ≈ƒ¥",
  178.         "≥Left  ≥≥≥≥",
  179.         "≥Right ≥≥≥≥",
  180.         "√ƒƒƒƒƒƒ≈ƒ¥                √ƒ¥",
  181.         "≥Bass  ≥≥≥≥",
  182.         "√ƒƒƒƒƒƒ≈ƒ¥                √ƒ¥",
  183.         "≥Treble≥≥≥≥",
  184.         "¿ƒƒƒƒƒƒ¡ƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¡ƒŸ",
  185.         "⁄ƒƒƒƒƒƒƒƒƒƒƒ¬ƒ¬ƒƒƒƒƒƒƒƒƒƒƒ¬ƒø",
  186.         "≥ Loudness  ≥≥ Enhanced  ≥≥",
  187.         "¿ƒƒƒƒƒƒƒƒƒƒƒ¡ƒ¡ƒƒƒƒƒƒƒƒƒƒƒ¡ƒŸ",
  188.  
  189.     };
  190.  
  191.     static char *screen3[] = {
  192.  
  193.         "ƒ…ÕÕÕÕÕÕª",
  194.         "∫Play &∫",
  195.         "∫Record∫",
  196.         "ƒÃÕÕÕÕÕÕπ",
  197.         "∫Play &∫",
  198.         "∫Record∫",
  199.         "ƒÃÕÕÕÕÕÕπ",
  200.         "∫Play &∫",
  201.         "∫Record∫",
  202.         "ƒÃÕÕÕÕÕÕπ",
  203.         "∫Play &∫",
  204.         "∫Record∫",
  205.         "ƒÃÕÕÕÕÕÕπ",
  206.         "∫Play &∫",
  207.         "∫Record∫",
  208.         "ƒÃÕÕÕÕÕÕπ",
  209.         "∫Play &∫",
  210.         "∫Record∫",
  211.         "ƒÃÀÀÀÀÀÀπ",
  212.         "ÃŒŒŒŒŒŒπ",
  213.         "ÃŒŒŒŒŒŒπ",
  214.         "ƒ»      º",
  215.  
  216.     };
  217.  
  218.     static char *screen3blank[]= {
  219.         "ƒÃÕÕÕÕÕÕπ",
  220.         "∫      ∫",
  221.         "∫      ∫"
  222.         };
  223.  
  224.  
  225.     static char *screen4[] = {       /* Help2rect                         */
  226.  
  227.         "⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø",
  228.         "≥ Type the F1 key for help. ≥",
  229.         "¿ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ"
  230.     };
  231.  
  232.     static char EffectsString[] = "±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±";
  233.  
  234.     static char *effectsbkgn[] = {
  235.         EffectsString,
  236.         EffectsString,
  237.         EffectsString,
  238.         EffectsString,
  239.         EffectsString,
  240.       EffectsString,
  241.         EffectsString,
  242.         EffectsString,
  243.         EffectsString,
  244.         EffectsString,
  245.         EffectsString,
  246.         EffectsString,
  247.         EffectsString,
  248.         EffectsString,
  249.         EffectsString,
  250.         EffectsString,
  251.         EffectsString,
  252.       EffectsString,
  253.       EffectsString,
  254.       EffectsString,
  255.       EffectsString,
  256.         EffectsString
  257.     };
  258.  
  259.     static char *screen5[] = {       /* input mixer helps                 */
  260.  
  261.         "⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø",
  262.         "≥    Channel Connections    ≥",
  263.         "√ƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒƒ¬ƒƒƒƒƒƒƒƒ¥",
  264.         "≥ Left   ≥≥ Left   ≥",
  265.         "≥ Left   ≥≥ Right  ≥",
  266.         "≥ Right  ≥≥ Left   ≥",
  267.         "≥ Right  ≥≥ Right  ≥",
  268.         "¿ƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒƒ¡ƒƒƒƒƒƒƒƒŸ"
  269.     };
  270.  
  271.     static char *screen6[] = {       /* input mixer helps                 */
  272.         "⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø",
  273.         "≥  Recording Monitor Level  ≥",
  274.         "√ƒƒƒƒƒƒ¬ƒ¬ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒ¥",
  275.         "≥Left  ≥≥≥≥",
  276.         "≥Right ≥≥≥≥",
  277.         "¿ƒƒƒƒƒƒ¡ƒ¡ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¡ƒŸ"
  278.     };
  279.  
  280.     static char *screen7[] = {       /* realsound switch                    */
  281.  
  282.         "⁄ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¬ƒø",
  283.         "≥   Real Sound Support    ≥≥",
  284.         "¿ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¡ƒŸ"
  285.     };
  286.  
  287.     static char playmsgi1[] = "Play &";
  288.     static char playmsgi2[] = "Record";
  289.     static char playmsgo1[] = "Play  ";
  290.     static char playmsgo2[] = "Only  ";
  291.  
  292.     static char *helpscreen[] = {
  293.  
  294.         "…ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕª",
  295. #if OEM
  296.         "∫           Spectrum            ∫",
  297.         "∫                               ∫",
  298. #else
  299.         "∫    Pro AudioSpectrum,  V1.21  ∫",
  300.         "∫      By Media Vision, Inc.    ∫",
  301. #endif
  302.         "«ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ∂",
  303.         "∫        Keyboard Control       ∫",
  304.         "∫       ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ      ∫",
  305.         "∫HOME  to decrease left volume  ∫",
  306.         "∫     to decrease both volumes ∫",
  307.         "∫ END  to decrease right volume ∫",
  308.         "∫PGUP  to increase left volume  ∫",
  309.         "∫  3   to increase both volumes ∫",
  310.         "∫PGDN  to increase right volume ∫",
  311.         "∫ENTER to toggle a button on/off∫",
  312.         "∫ TAB  to move between fields   ∫",
  313.         "∫ F4   reset mixer to defaults  ∫",
  314.         "∫ F2   special effects          ∫",
  315.         "∫F5-F8 load mixer settings (use ∫",
  316.         "∫      Shifted-FKEY to save)    ∫",
  317.         "∫ ESC  will exit all dialogs    ∫",
  318.         "∫       ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ      ∫",
  319.         "∫       Copyright (c) 1991      ∫",
  320.         "∫      All Rights Reserved.     ∫",
  321.         "»ÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕº"
  322.     };
  323.  
  324.  
  325.         static char twobar[]            = "˙˙˙˙˙˘˘˘˘˘";
  326.         static char channelconnect[]    = "";
  327.         static char channeldisconnect[] = "˙ ˙ ˙ ˙ ˙";
  328.  
  329.         extern char leftswitch;
  330.         extern int    leftvolume;
  331.         extern char ritswitch;
  332.         extern int    ritvolume;
  333.         extern int    VolumeNumber;
  334.         extern char VolumeSwitch;
  335.         extern int    Left2LeftState;
  336.         extern int    Left2RightState;
  337.         extern int    Right2LeftState;
  338.         extern int    Right2RightState;
  339.  
  340.     //    static char NumLockState;
  341.  
  342.         static VideoStruct OurWnd = { 0,0,0x18,0x4f, 0,0, 0x1f,0, 0,0xb800 };
  343.         VideoStruct *CurWnd = &OurWnd;
  344.         unsigned int VideoSegment = 0xb800;
  345.  
  346.         static rect Help1Rect  = { 1,23, 23,57 };
  347.         static rect Help2Rect  = {19,47, 21,77 };
  348.         static rect MixerRect  = { 0, 2, 23,36 };
  349.         static rect RecordRect = { 2,35, 23,45 };
  350.         static rect VolRect    = { 4,47, 16,77 };
  351.         static rect EffectsRect = { 1,20, 22,60 };
  352.         static rect Screen6Rect = { 2,25,  7,55 };
  353.         static rect Screen5Rect = { 9,25, 16,55 };
  354.         static rect Screen7Rect = {18,25, 20,55 };
  355.  
  356.     /* file handle for accessing MVPROAS                                */
  357.  
  358.         static int    mv;             /* mvsound dos driver                */
  359.  
  360.     /* objects                                                            */
  361.  
  362. #define OBJ_SCROLL        1
  363. #define OBJ_VOLUME        2
  364. #define OBJ_BUTTON        3
  365.  
  366.         typedef struct {
  367.             int  type;                // structure type
  368.             void *next;             // next structure pointer
  369.             void *back;             // prior structure pointer
  370.             int (*scr)();            // object processor
  371.             int (*swi)();            // object processor
  372.             rect namr;                // channel name rectangle
  373.             rect scrr;                // scroll bar rectangle
  374.             rect swir;                // record mixer select switch rectangle
  375.             char name[10];            // channel name "mic"/"ext", etc
  376.             int leftchannel;        // current left channel setting
  377.             int ritchannel;         // current right channel setting
  378.             int mixerselect;        // choosen mixer
  379.             int deadlchannel;        // current left channel setting
  380.             int deadrchannel;        // current right channel setting
  381.             int deadmixer;            // choosen mixer
  382.  
  383.         } Scroll, *SPtr;
  384.  
  385.         typedef struct {
  386.             int  type;                // structure type
  387.             void *next;             // next structure pointer
  388.             void *back;             // prior structure pointer
  389.             int (*scr)();            // object processor
  390.             rect namr;                // channel name rectangle
  391.             rect scrr;                // scroll bar rectangle
  392.             char name[20];            // channel name "mic"/"ext", etc
  393.             int channel;            // current channel setting
  394.         } Volume, *VPtr;
  395.  
  396.         typedef struct {
  397.             int  type;                // structure type
  398.             void *next;             // next structure pointer
  399.             void *back;             // prior structure pointer
  400.             int (*scr)();            // object processor
  401.             rect namr;                // channel name rectangle
  402.             rect scrr;                // scroll bar rectangle
  403.             char name[20];            // channel name "mic"/"ext", etc
  404.             int state;                // current button state
  405.         } Button, *BPtr;
  406.  
  407.         typedef struct {
  408.             void *head;
  409.             void *tail;
  410.             void *nextlist;
  411.         } ObjectList, *OLPtr;
  412.  
  413.     // Scroll bar objects
  414.  
  415.         static Scroll SynthScroll;           // structure prototypes
  416.         static Scroll ExtScroll;
  417.         static Scroll IntScroll;
  418.         static Scroll MicScroll;
  419.         static Scroll DigitalScroll;
  420.         static Scroll TBScroll;
  421.         static Scroll SpkrScroll;
  422.         static Scroll OutputMixerScroll;
  423.  
  424.         static Volume LeftVolumeLevel;
  425.         static Volume RitVolumeLevel;
  426.         static Volume BassVolume;
  427.         static Volume TrebVolume;
  428.  
  429.         static Button Loudness;
  430.         static Button Enhanced;
  431.         static Button Left2Left;
  432.         static Button Left2Right;
  433.         static Button Right2Left;
  434.         static Button Right2Right;
  435.         static Button RealSoundButton;
  436.  
  437.         static ObjectList MainList;
  438.         static ObjectList EffectsList;
  439.  
  440.         static ObjectList MainList = {
  441.             &SynthScroll,
  442.             &Enhanced,
  443.             &EffectsList
  444.         };
  445.  
  446.         static ObjectList EffectsList = {
  447.             &OutputMixerScroll,
  448.             &RealSoundButton,
  449.             0
  450.         };
  451.  
  452.         static OLPtr   CurrList = &MainList;
  453.  
  454.         static Scroll *CurrentObject = &SynthScroll;  // current object pointer
  455.  
  456.         static Scroll SynthScroll = {
  457.             OBJ_SCROLL,
  458.             &ExtScroll,
  459.             0,
  460.             &ScrollObjectHandler,
  461.             &SwitchObjectHandler,
  462.              3, 3, 4,14,
  463.              3,18, 4,33,
  464.              3,37, 4,42,
  465.             "FM ",
  466.             0,
  467.             0,
  468.             0,0,0,0
  469.         };
  470.  
  471.         static Scroll ExtScroll = {
  472.             OBJ_SCROLL,
  473.             &IntScroll,
  474.             &SynthScroll,
  475.             &ScrollObjectHandler,
  476.             &SwitchObjectHandler,
  477.              6, 3, 7,14,
  478.              6,18, 7,33,
  479.              6,37, 7,42,
  480.             "EXT ",
  481.             0,
  482.             0,
  483.             0,0,0,0
  484.         };
  485.  
  486.         static Scroll IntScroll = {
  487.             OBJ_SCROLL,
  488.             &MicScroll,
  489.             &ExtScroll,
  490.             &ScrollObjectHandler,
  491.             &SwitchObjectHandler,
  492.              9, 3,10,14,
  493.              9,18,10,33,
  494.              9,37,10,42,
  495.             "INT ",
  496.             0,
  497.             0,
  498.             0,0,0,0
  499.         };
  500.  
  501.         static Scroll MicScroll = {
  502.             OBJ_SCROLL,
  503.             &SpkrScroll,
  504.             &IntScroll,
  505.             &ScrollObjectHandler,
  506.             &SwitchObjectHandler,
  507.             12, 3,13,14,
  508.             12,18,13,33,
  509.             12,37,13,42,
  510.             "MIC ",
  511.             0,
  512.             0,
  513.             0,0,0,0
  514.         };
  515.  
  516.         static Scroll SpkrScroll = {
  517.             OBJ_SCROLL,
  518.             &TBScroll,
  519.             &MicScroll,
  520.             &ScrollObjectHandler,
  521.             &SwitchObjectHandler,
  522.             15, 3,16,14,
  523.             15,18,16,33,
  524.             15,37,16,42,
  525.             "SPEAKER ",
  526.             0,
  527.             0,
  528.             0,0,0,0
  529.         };
  530.  
  531.         static Scroll TBScroll = {
  532.             OBJ_SCROLL,
  533.             &DigitalScroll,
  534.             &SpkrScroll,
  535.             &ScrollObjectHandler,
  536.             &SwitchObjectHandler,
  537.             18, 3,19,14,
  538.             18,18,19,33,
  539.             18,37,19,42,
  540.             "SB      ",
  541.             0,
  542.             0,
  543.             0,0,0,0
  544.         };
  545.  
  546.         static Scroll DigitalScroll = {
  547.             OBJ_SCROLL,
  548.             &LeftVolumeLevel,
  549.             &TBScroll,
  550.             &ScrollObjectHandler,
  551.             0,
  552.             21, 3,22,14,
  553.             21,18,22,33,
  554.             21,37,22,42,
  555.             "PCM ",
  556.             0,
  557.             0,
  558.             0,0,0,0
  559.         };
  560.  
  561.         static Volume LeftVolumeLevel = {
  562.             OBJ_VOLUME,
  563.             &BassVolume,
  564.             &DigitalScroll,
  565.             &VolumeLevels,
  566.              7,48, 7,53,
  567.              7,57, 7,72,
  568.             "LEVEL ",
  569.             0
  570.         };
  571.  
  572.             // this object is owned byte LeftVolumeLevel
  573.  
  574.                 static Volume RitVolumeLevel  = {
  575.                     OBJ_VOLUME,
  576.                     0,
  577.                     0,
  578.                     &VolumeLevels,
  579.                      8,48, 8,53,
  580.                      8,57, 8,72,
  581.                     "LEVEL ",
  582.                     0
  583.                 };
  584.  
  585.         static Volume BassVolume = {
  586.             OBJ_VOLUME,
  587.             &TrebVolume,
  588.             &LeftVolumeLevel,
  589.             &EqualizerLevels,
  590.             10,48,10,53,
  591.             10,57,10,72,
  592.             "BASS ",
  593.             0
  594.         };
  595.  
  596.         static Volume TrebVolume = {
  597.             OBJ_VOLUME,
  598.             &Loudness,
  599.             &BassVolume,
  600.             &EqualizerLevels,
  601.             12,48,12,53,
  602.             12,57,12,72,
  603.             "TREBLE ",
  604.             0
  605.         };
  606.  
  607.         static Button Loudness    = {
  608.             OBJ_BUTTON,
  609.             &Enhanced,
  610.             &TrebVolume,
  611.             &VolumeButtons,
  612.             15,48,15,58,
  613.             15,60,15,60,
  614.             "LOUDNESS ",
  615.             0
  616.         };
  617.  
  618.         static Button Enhanced = {
  619.             OBJ_BUTTON,
  620.             0,
  621.             &Loudness,
  622.             &VolumeButtons,
  623.             15,63,15,72,
  624.             15,74,15,74,
  625.             "ENHANCED ",
  626.             0
  627.         };
  628.  
  629.  
  630.     /*\
  631.     |*| effects dialog box structures
  632.     \*/
  633.  
  634.         static Scroll OutputMixerScroll = {
  635.             OBJ_SCROLL,
  636.             &Left2Left,
  637.             0,
  638.             &ScrollObjectHandler,
  639.             0,
  640.             5,26,6,31,
  641.             5,35,6,50,
  642.              0, 0, 0, 0,
  643.             "MIXER ",
  644.             0,
  645.             0,
  646.             0,0,0,0
  647.         };
  648.  
  649.         static Button Left2Left = {
  650.             OBJ_BUTTON,
  651.             &Left2Right,
  652.             &OutputMixerScroll,
  653.             &EffectsButtons,
  654.             12,26,12,33,
  655.             12,35,12,43,
  656.             "Left to Left ",
  657.             0
  658.         };
  659.  
  660.         static Button Left2Right = {
  661.             OBJ_BUTTON,
  662.             &Right2Left,
  663.             &Left2Left,
  664.             &EffectsButtons,
  665.             13,26,13,33,
  666.             13,35,13,43,
  667.             "Left to Right ",
  668.             0
  669.         };
  670.  
  671.         static Button Right2Left = {
  672.             OBJ_BUTTON,
  673.             &Right2Right,
  674.             &Left2Right,
  675.             &EffectsButtons,
  676.             14,26,14,33,
  677.             14,35,14,43,
  678.             "Right to Left ",
  679.             0
  680.         };
  681.  
  682.         static Button Right2Right = {
  683.             OBJ_BUTTON,
  684.             &RealSoundButton,
  685.             &Right2Left,
  686.             &EffectsButtons,
  687.             15,26,15,33,
  688.             15,35,15,43,
  689.             "Right to Right ",
  690.             0
  691.         };
  692.  
  693.         static Button RealSoundButton = {
  694.             OBJ_BUTTON,
  695.             0,
  696.             &Right2Left,
  697.             &EffectsButtons,
  698.             19,26,19,49,
  699.             19,52,19,52,
  700.             " ",
  701.             0
  702.         };
  703.  
  704.         static int OrigRow;            // original row position
  705.         static int OrigCol;            // original column position
  706.  
  707.         static char CommandString[80]; // text buffer that holds commands to MVPROAS
  708.         static char MVResponse[80];    // text buffer that holds the MVPROAS responses
  709.  
  710.         static int screenbuffer[2048]; // screen backup buffer
  711.  
  712. #define MAIN_DLG        0x0001    // main screen dialog boxes
  713. #define EFFECTS_DLG     0x0002    // recording effects dialog box
  714.  
  715.         static int DialogBox=MAIN_DLG; // bit field indicating witch dialog box is up
  716.  
  717.  
  718.         typedef struct {
  719.  
  720.             int Filler;         // all other screen area
  721.  
  722.             int BkGn_AND;       // background AND mask
  723.             int BkGn_XOR;        // background XOR mask
  724.  
  725.             int Shdw_AND;       // shadow AND mask
  726.             int Shdw_XOR;        // shadow XOR mask
  727.  
  728.             int TmpHi_AND;      // temp High AND mask
  729.             int TmpHi_XOR;        // temp high XOR mask
  730.  
  731.             int TmpLo_AND;      // temp low  AND mask
  732.             int TmpLo_XOR;        // temp low  XOR mask
  733.  
  734.             int ScrTmpHi_AND;    // temp High AND mask
  735.             int ScrTmpHi_XOR;    // temp high XOR mask
  736.  
  737.             int ScrTmpLo_AND;    // temp low  AND mask
  738.             int ScrTmpLo_XOR;    // temp low  XOR mask
  739.  
  740.             int ButLo_AND;      // button low AND mask
  741.             int ButLo_XOR;        // button low XOR mask
  742.  
  743.             int ButHi_AND;      // button high AND mask
  744.             int ButHi_XOR;        // button high XOR mask
  745.  
  746.         } scheme, *SCMPtr;
  747.  
  748.         static scheme MonoScheme = {   // attribute control for MONO screens
  749.  
  750.             0x0e,                // full bright
  751.  
  752.             0x00,                // background AND mask
  753.             0x07,                // background XOR mask
  754.  
  755.             0x77,                // shadow AND mask
  756.             0x00,                // shadow XOR mask
  757.  
  758.             0x77,                // temp High AND mask
  759.             0x08,                // temp high XOR mask
  760.  
  761.             0x77,                // temp low  AND mask
  762.             0x00,                // temp low  XOR mask
  763.  
  764.             0x77,                // scroll temp High AND mask
  765.             0x08,                // scroll temp high XOR mask
  766.  
  767.             0x77,                // scroll temp low    AND mask
  768.             0x00,                // scroll temp low    XOR mask
  769.  
  770.             0x00,                // button low AND mask
  771.             0x1f,                // button low XOR mask
  772.  
  773.             0x08,                // button high AND mask
  774.             0x70,                // button high XOR mask
  775.  
  776.         };
  777.  
  778.         static scheme ColorScheme = {  // attribute control for COLOR screens
  779.  
  780.             0x09,                // bright blue background
  781.  
  782.             0x00,               // background AND mask
  783.             0x30,                // background XOR mask
  784.  
  785.             0x00,                // shadow AND mask
  786.             0x00,                // shadow XOR mask
  787.  
  788.             0x70,                // temp High AND mask
  789.             0x0e,                // temp high XOR mask
  790.  
  791.             0x70,                // temp low  AND mask
  792.             0x00,                // temp low  XOR mask
  793.  
  794.             0x70,                // scroll temp High AND mask
  795.             0x0e,                // scroll temp high XOR mask
  796.  
  797.             0x70,                // scroll temp low    AND mask
  798.             0x0a,                // scroll temp low    XOR mask
  799.  
  800.             0x00,                // button low AND mask
  801.             0x37,                // button low XOR mask
  802.  
  803.             0x00,                // button high AND mask
  804.             0x3f,                // button high XOR mask
  805.  
  806.         };
  807.  
  808.         static scheme HelpsColorScheme = {    // attribute control for COLOR screens
  809.  
  810.             0x09,                // bright blue
  811.  
  812.             0x00,               // background AND mask
  813.             0x20,                // background XOR mask
  814.  
  815.             0x00,                // shadow AND mask
  816.             0x00,                // shadow XOR mask
  817.  
  818.             0x77,                // temp High AND mask
  819.             0x08,                // temp high XOR mask
  820.  
  821.             0x77,                // temp low  AND mask
  822.             0x00,                // temp low  XOR mask
  823.  
  824.             0x77,                // scroll temp High AND mask
  825.             0x08,                // scroll temp high XOR mask
  826.  
  827.             0x77,                // scroll temp low    AND mask
  828.             0x00,                // scroll temp low    XOR mask
  829.  
  830.             0x08,                // button low AND mask
  831.             0x17,                // button low XOR mask
  832.  
  833.             0x08,                // button high AND mask
  834.             0x70,                // button high XOR mask
  835.  
  836.         };
  837.  
  838.         static SCMPtr  Colors = &ColorScheme;  // default to color adapber scheme
  839.  
  840.  
  841.     /*\
  842.     |*|----====< more prototypes >====----
  843.     \*/
  844.  
  845.         int            MixerDialogInit       ( );
  846.         int            MixerDialogHalt       ( );
  847.         static int       BroadcastMsg        ( int );
  848.         static int       BroadcastToLlist    ( int, ObjectList * );
  849.         static void    DrawScreen           ( rect *, char *([]) );
  850.         static int       GetEvent            ( EPtr );
  851.         static void    MatchObj            ( EPtr );
  852.         static void    PaintScreen           ( int, int );
  853.         static int       PtInRect            ( point *,rect * );
  854.         static int       SendMixer           ( char *, int, int, SPtr, int, int );
  855.         static int       SendVolume           ( char *, int, VPtr, int, int );
  856.  
  857.         static int       SystemKey           ( EPtr );
  858.         static int       SystemInit           ( );
  859.         static void    SystemShutDown       ( );
  860.  
  861.         extern void    BackupVideo           ( rect *, char far *, int, int );
  862.         extern void    RestoreVideo        ( rect *, char far *, int, int );
  863.         long extern    _videogetcurs       ( );  /* ***** was near kdn */
  864.  
  865.  
  866.     /*\
  867.     |*|----------------==============================----------------
  868.     |*|----------------====< Start of Execution >====----------------
  869.     |*|----------------==============================----------------
  870.     \*/
  871.  
  872.         static int exitcode = FALSE;    // our exit flag
  873.         static int CallersFillChar;     // Callers screen fill char (0) for none
  874.  
  875. MixerDialogBox(fill)
  876.     int fill;
  877. {
  878. Event ev;
  879. char *s;
  880.  
  881.     /* make the fill character available to the masses                    */
  882.  
  883.         s = EffectsString;
  884.         if ((CallersFillChar = fill) != 0)
  885.             while (*s) *s++ = fill;
  886.  
  887.     /* initialize the hardware.                                         */
  888.  
  889.         SystemInit();
  890.  
  891.     /* go forever                                                        */
  892.  
  893.         while (!exitcode) {
  894.  
  895.             /* if a keyboard/mouse action, the pass to handlers         */
  896.  
  897.                 if (GetEvent (&ev)) {
  898.                     if (!SystemKey(&ev)) {
  899.                         if (CurrentObject)
  900.                             (*CurrentObject->scr)(OPEVENT,CurrentObject,&ev);
  901.                     }
  902.                 }
  903.  
  904.             /* if no action, just move the cross hairs                    */
  905.  
  906.                 else
  907.                     UpdateTotalVolume();        /* changes via keyboard */
  908.                     MatchObj ( &ev );           /* find a new object    */
  909.         }
  910.  
  911.     /* exit back to caller                                                */
  912.  
  913.         SystemShutDown();
  914.  
  915.     /* reset the exit code so we can process again...                    */
  916.  
  917.         exitcode=FALSE;
  918.  
  919. }
  920.  
  921.  
  922.     /*\
  923.     |*|----====< MixerGetSettings() >====----
  924.     |*|
  925.     |*| call the user back with the appropriate data
  926.     |*|
  927.     |*| Entry Conditions:
  928.     |*|     None
  929.     |*|
  930.     |*| Exit Conditions:
  931.     |*|     0 = okay, !0 = failure
  932.     |*|
  933.     \*/
  934.  
  935. MixerGetSettings(c)
  936.     void (*c)();
  937. {
  938. SPtr o;
  939. OLPtr l;
  940.  
  941.     /* start at the top & send to all objects, even the caller            */
  942.  
  943.         l = &MainList;
  944.  
  945.         while (l) {
  946.  
  947.             o = l->head;
  948.  
  949.             while (o) {
  950.  
  951.                 // send the message to the next object
  952.  
  953.                     (*o->scr)(OPENINIT,o);
  954.  
  955.                     // if the dead mixer, then send this string too!
  956.  
  957.                     if (o->type == OBJ_SCROLL) {
  958.                         SendMixer ("SET ",o->deadmixer,1,o,BI_SETTO,o->deadlchannel);
  959.                         (*c)(&CommandString);
  960.                         SendMixer ("SET ",o->deadmixer,2,o,BI_SETTO,o->deadrchannel);
  961.                         (*c)(&CommandString);
  962.                     }
  963.                     (*o->scr)(SENDIT,o,c);
  964.  
  965.                 // go to next object
  966.  
  967.                     o = o->next;
  968.             }
  969.  
  970.             l = l->nextlist;
  971.         }
  972. }
  973.  
  974.  
  975.     /*\
  976.     |*|----====< MixerDialogInit() >====----
  977.     |*|
  978.     |*| Perform any startup needed
  979.     |*|
  980.     |*| Entry Conditions:
  981.     |*|     None
  982.     |*|
  983.     |*| Exit Conditions:
  984.     |*|     0 = okay, !0 = failure
  985.     |*|
  986.     \*/
  987. int MixerDialogInit()
  988. {
  989.  
  990.     // open the device
  991.  
  992.         //if ((mv = open ("MVPROAS",O_RDWR, S_IREAD | S_IWRITE)) == -1) {
  993.  
  994.         if ((mv = open ("MVPROAS",O_RDWR )) == -1) {
  995.           //_ttyout ("\acannot open the MVPROAS device!\n",0);
  996.             return(1);
  997.         }
  998.  
  999.     // make an IBM PC right arrow appear in some text
  1000.  
  1001.         helpscreen[10][3]= 26;    /* used to be:        hackaline[3] = 26; */
  1002.  
  1003.     // everything is fine...
  1004.  
  1005.         return (0);
  1006.  
  1007. }
  1008.  
  1009.  
  1010.     /*\
  1011.     |*|----====< MixerDialogHalt() >====----
  1012.     |*|
  1013.     |*| Perform any other shutdown
  1014.     |*|
  1015.     |*| Entry Conditions:
  1016.     |*|     None
  1017.     |*|
  1018.     |*| Exit Conditions:
  1019.     |*|     0 = okay, !0 = failure
  1020.     |*|
  1021.     \*/
  1022. int  MixerDialogHalt()
  1023. {
  1024.  
  1025.     // close down the file handle
  1026.  
  1027.         close (mv);
  1028.  
  1029.     // everything is fine...
  1030.  
  1031.         return (0);
  1032.  
  1033. }
  1034.  
  1035.  
  1036.     /*\
  1037.     |*|--------------------=======================--------------------
  1038.     |*|--------------------====< Subroutines >====--------------------
  1039.     |*|--------------------=======================--------------------
  1040.     \*/
  1041.  
  1042.  
  1043.     /*\
  1044.     |*|----====< void BroadcastMsg ( int ) >====----
  1045.     |*|
  1046.     |*|    This routine broadcasts a message to all objects.
  1047.     |*|
  1048.     \*/
  1049. static int BroadcastMsg (msg)
  1050.     int msg;
  1051. {
  1052. SPtr o;
  1053.  
  1054.     /* send to all linked lists of objects                                */
  1055.  
  1056.         BroadcastToList (msg,&MainList);
  1057.         BroadcastToList (msg,&EffectsList);
  1058. }
  1059.  
  1060.  
  1061.     /*\
  1062.     |*|----====< void BroadcastToList ( int, ObjectList * ) >====----
  1063.     |*|
  1064.     |*|    This routine broadcasts a message to all objects.
  1065.     |*|
  1066.     \*/
  1067. static int BroadcastToList (msg,l)
  1068.     int msg;
  1069.      ObjectList *l;
  1070. {
  1071. SPtr o;
  1072.  
  1073.     /* start at the top & send to all objects, even the caller            */
  1074.  
  1075.         o = l->head;
  1076.  
  1077.         while (o) {
  1078.  
  1079.             /* send the message to the next object                        */
  1080.  
  1081.                 (*o->scr)(msg,o);
  1082.  
  1083.             /* go to next object                                        */
  1084.  
  1085.                 o = o->next;
  1086.         }
  1087. }
  1088.  
  1089.  
  1090. #if 0
  1091.     /*\
  1092.     |*|----====< void DupTheEvent ( EPtr, EPtr ); >====----
  1093.     |*|
  1094.     |*|    Duplicate our event record.
  1095.     |*|
  1096.     \*/
  1097.         void    DupTheEvent         ( EPtr, EPtr );
  1098. static void DupTheEvent(src,dst)
  1099.     EPtr src,dst;
  1100. {
  1101.  
  1102.     /* duplicate the event using an intrinsic function                    */
  1103.  
  1104.         memcpy
  1105.           (
  1106.             (char *) dst,
  1107.             (char *) src,
  1108.             sizeof (Event)
  1109.           );
  1110. }
  1111. #endif
  1112.  
  1113.  
  1114.     /*\
  1115.     |*|----====< int EffectsButtons() >====----
  1116.     |*|
  1117.     |*| Cross Channel object control
  1118.     |*|
  1119.     |*| Entry Conditions:
  1120.     |*|     None
  1121.     |*|
  1122.     |*| Exit Conditions:
  1123.     |*|     None
  1124.     |*|
  1125.     \*/
  1126. static int EffectsButtons(msg,o,ptr)
  1127.     int msg;
  1128.     BPtr o;
  1129.     void *ptr;
  1130. {
  1131. void **pptr;
  1132. rect r;
  1133. int l,ri,i;
  1134. char c1,c2;
  1135.  
  1136.     // get a pointer to the stack
  1137.  
  1138.         pptr = &ptr;
  1139.  
  1140.     // process the message
  1141.  
  1142.         switch (msg) {
  1143.  
  1144.             case OPEVENT:
  1145.  
  1146.                 switch (((EPtr)pptr[0])->buttons) {
  1147.  
  1148.                     case ENTER:
  1149.  
  1150.                         // ENTER here can toggle the buttons
  1151.  
  1152.                        o->state = ((o->state) ? FALSE : TRUE );
  1153.  
  1154.                         (*o->scr) (DRAWIT,o);
  1155.  
  1156.                         if (o == &RealSoundButton)
  1157.                             SendOnOff ("SET ","REALSOUND ",o);
  1158.                         else
  1159.                             SendOnOff ("SET ","CROSS ",o);
  1160.  
  1161.                         break;
  1162.  
  1163.                     default:
  1164.                         break;
  1165.                 }
  1166.  
  1167.                 break;
  1168.  
  1169.             case SENDIT:
  1170.  
  1171.                 if (o == &RealSoundButton)
  1172.                     SendOnOff ("SET ","REALSOUND ",o);
  1173.                 else
  1174.                     SendOnOff ("SET ","CROSS ",o);
  1175.  
  1176.                 (*(void(*)())ptr)(&CommandString);
  1177.  
  1178.                 break;
  1179.  
  1180.             case FOCUS_GIVEN:
  1181.  
  1182.                 // highlight the entire field
  1183.  
  1184.                     if (o == &RealSoundButton) {
  1185.  
  1186.                       //r.row2 = o->namr.row2;
  1187.                       //r.row1 = o->namr.row1;
  1188.                       //r.col2 = r.col1 = o->namr.col2+2;
  1189.                       //_videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  1190.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1191.                         _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1192.  
  1193.                     }
  1194.                     else {
  1195.  
  1196.                         r.row1 = o->scrr.row1;
  1197.                         r.row2 = o->scrr.row2;
  1198.                         r.col2 = (r.col1 = o->scrr.col2+2) + 7;
  1199.  
  1200.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1201.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r );
  1202.                         _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1203.                     }
  1204.  
  1205.                     break;
  1206.  
  1207.             case FOCUS_TAKEN:
  1208.  
  1209.                 // remove the highlight from the entire field
  1210.  
  1211.                     if (o == &RealSoundButton) {
  1212.  
  1213.                       //r.row1 = o->namr.row1;
  1214.                       //r.row2 = o->namr.row2;
  1215.                       //r.col2 = r.col1 = o->namr.col2+2;
  1216.                       //_videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &r       );
  1217.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  1218.                         _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1219.  
  1220.                     }
  1221.                     else {
  1222.                         r.row1 = o->scrr.row1;
  1223.                         r.row2 = o->scrr.row2;
  1224.                         r.col2 = (r.col1 = o->scrr.col2+2) + 7;
  1225.  
  1226.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  1227.                         _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1228.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &r );
  1229.                     }
  1230.  
  1231.                     break;
  1232.  
  1233.             case DRAWIT:
  1234.  
  1235.                 // move the cursor to the slide bar area
  1236.  
  1237.                     if (o == &RealSoundButton) {
  1238.  
  1239.                         _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1240.  
  1241.                         if (o->state)
  1242.                             _zipout   ( "X" );
  1243.                         else
  1244.                             _zipout   ( "˘" );
  1245.                     }
  1246.  
  1247.                     else {
  1248.  
  1249.                         _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1250.  
  1251.                         if (o->state)
  1252.                             _zipout ( channelconnect, 0);
  1253.                         else
  1254.                             _zipout ( channeldisconnect, 0);
  1255.                     }
  1256.  
  1257.                 break;
  1258.  
  1259.             case OPENINIT:
  1260.  
  1261.                 // get the output mixer current state
  1262.  
  1263.                     if (o == &RealSoundButton) {
  1264.  
  1265.                         SendOnOff ("GET ","REALSOUND ",o);
  1266.  
  1267.                         o->state = (MVResponse[0] == '+') ? TRUE : FALSE;
  1268.  
  1269.                     }
  1270.                     else {
  1271.  
  1272.                         SendOnOff ("GET ","CROSS ",o);
  1273.  
  1274.                         DecodeCrossChannel (MVResponse);
  1275.  
  1276.                         if (o == &Left2Left)
  1277.                             o->state = Left2LeftState;
  1278.  
  1279.                         if (o == &Left2Right)
  1280.                             o->state = Left2RightState;
  1281.  
  1282.                         if (o == &Right2Left)
  1283.                             o->state = Right2LeftState;
  1284.  
  1285.                         if (o == &Right2Right)
  1286.                             o->state = Right2RightState;
  1287.                     }
  1288.  
  1289.                     break;
  1290.  
  1291.             case CLEARIT:
  1292.             default:
  1293.                 break;
  1294.         }
  1295. }
  1296.  
  1297.  
  1298.  
  1299.     /*\
  1300.     |*|----====< int EqualizerLevels() >====----
  1301.     |*|
  1302.     |*| BASS/TREBLE slide bar object control
  1303.     |*|
  1304.     |*| Entry Conditions:
  1305.     |*|     None
  1306.     |*|
  1307.     |*| Exit Conditions:
  1308.     |*|     None
  1309.     |*|
  1310.     \*/
  1311. static int EqualizerLevels(msg,o,ptr)
  1312.     int msg;
  1313.     VPtr o;
  1314.     void *ptr;
  1315. {
  1316. void **pptr;
  1317. rect r;
  1318. int l,ri,i;
  1319. char c1,c2;
  1320.  
  1321.     // get a pointer to the stack
  1322.  
  1323.         pptr = &ptr;
  1324.  
  1325.     // process the message
  1326.  
  1327.         switch (msg) {
  1328.  
  1329.             case OPEVENT:
  1330.  
  1331.                 switch (((EPtr)pptr[0])->buttons) {
  1332.  
  1333.                     case ENDKEY:
  1334.                     case HOMEKEY:
  1335.                     case LFARROW:
  1336.  
  1337.                         if (o->channel > 0)
  1338.                             o->channel -= 4;
  1339.  
  1340.                         SendVolume
  1341.                           (
  1342.                             "SET ",
  1343.                             0,
  1344.                             o,
  1345.                             BI_SETTO,
  1346.                             o->channel
  1347.                           );
  1348.  
  1349.                         (*o->scr) (DRAWIT,o);
  1350.  
  1351.                         break;
  1352.  
  1353.                     case PGDNKEY:
  1354.                     case PGUPKEY:
  1355.                     case RIARROW:
  1356.  
  1357.                         if (o->channel < 100)
  1358.                             o->channel += 4;
  1359.  
  1360.                         SendVolume
  1361.                           (
  1362.                             "SET ",
  1363.                             0,
  1364.                             o,
  1365.                             BI_SETTO,
  1366.                             o->channel
  1367.                           );
  1368.  
  1369.                         (*o->scr) (DRAWIT,o);
  1370.  
  1371.                         break;
  1372.  
  1373.                     case ENTER:
  1374.  
  1375.                         // ENTER here can toggle the buttons
  1376.  
  1377.                         if (o == &BassVolume)
  1378.                             (*Loudness.scr)(msg,&Loudness,ptr);
  1379.  
  1380.                         if (o == &TrebVolume)
  1381.                             (*Enhanced.scr)(msg,&Enhanced,ptr);
  1382.                         break;
  1383.  
  1384.                     default:
  1385.                         break;
  1386.                 }
  1387.  
  1388.                 break;
  1389.  
  1390.             case SENDIT:
  1391.  
  1392.                 SendVolume
  1393.                   (
  1394.                     "SET ",
  1395.                     0,
  1396.                     o,
  1397.                     BI_SETTO,
  1398.                     o->channel
  1399.                   );
  1400.                 (*(void(*)())ptr)(&CommandString);
  1401.  
  1402.                 break;
  1403.  
  1404.             case FOCUS_GIVEN:
  1405.  
  1406.                 // highlight the entire field
  1407.  
  1408.                     r.row1 = o->namr.row1;
  1409.                     r.row2 = o->namr.row2;
  1410.                     r.col2 = r.col1 = o->namr.col2+2;
  1411.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1412.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  1413.  
  1414.                     r.row1 = o->scrr.row1;
  1415.                     r.row2 = o->scrr.row2;
  1416.                     r.col2 = r.col1 = o->scrr.col2+2;
  1417.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1418.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  1419.  
  1420.                     break;
  1421.  
  1422.             case FOCUS_TAKEN:
  1423.  
  1424.                 // highlight the entire field
  1425.  
  1426.                     r.row1 = o->namr.row1;
  1427.                     r.row2 = o->namr.row2;
  1428.                     r.col2 = r.col1 = o->namr.col2+2;
  1429.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,    &o->namr );
  1430.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1431.  
  1432.                     r.row1 = o->scrr.row1;
  1433.                     r.row2 = o->scrr.row2;
  1434.                     r.col2 = r.col1 = o->scrr.col2+2;
  1435.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1436.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1437.  
  1438.                     break;
  1439.  
  1440.             case DRAWIT:
  1441.  
  1442.                 // move the cursor to the slide bar area
  1443.  
  1444.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1445.                     _zipout       ( twobar, 0);
  1446.  
  1447.                     l = (o->channel * 31) / 100;
  1448.                     _videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
  1449.                     _zipout (((l & 1) ? "fi" : "›"), 0);
  1450.  
  1451.                     break;
  1452.  
  1453.             case OPENINIT:
  1454.  
  1455.                 // get the output mixer current state
  1456.  
  1457.                     SendVolume ("GET ",0,o,0,0);
  1458.                     DecodeVolumeNumber (MVResponse);
  1459.                     o->channel = VolumeNumber;
  1460.  
  1461.                     break;
  1462.  
  1463.             case CLEARIT:
  1464.             default:
  1465.                 break;
  1466.         }
  1467. }
  1468.  
  1469.  
  1470.     /*\
  1471.     |*|----====< int GetEvent ( EPtr ) >====----
  1472.     |*|
  1473.     |*|   This routine fetches the next event from the mouse driver
  1474.     |*|
  1475.     |*| This routine is used by permission from Douglas S. Cody
  1476.     |*| Douglas S. Cody, Copyright 1989,1990 (c), All Rights Reserved.
  1477.     |*|
  1478.     \*/
  1479. static int GetEvent (e)
  1480.     EPtr e;
  1481. {
  1482.  
  1483.     // if there is a key waiting...
  1484.  
  1485.         if (_bios_keybrd( _KEYBRD_READY )) {
  1486.  
  1487.             // ...return it
  1488.  
  1489.             e->type = EV_KEYB;
  1490.             return (e->buttons =  _bios_keybrd ( _KEYBRD_READ ));
  1491.         }
  1492.  
  1493.     // ...else return 0
  1494.  
  1495.         return( 0 );
  1496.  
  1497. }
  1498.  
  1499.  
  1500.     /*\
  1501.     |*|----====< void MatchObj(EPtr) >====----
  1502.     |*|
  1503.     |*|    This routine matches the mouse pointer to a screen object
  1504.     |*|
  1505.     \*/
  1506. static void MatchObj(e)
  1507.     EPtr e;
  1508. {
  1509. SPtr o;
  1510.  
  1511. #if 0
  1512.     // if this is a mouse type, match it to the list
  1513.  
  1514.         if (e->type == EV_MOUS) {
  1515.  
  1516.             // if point is still within the current object, just return
  1517.  
  1518.                 if (PtInRect ((point *)&e->vpos,&CurrentObject->scrr) ||
  1519.                     PtInRect ((point *)&e->vpos,&CurrentObject->scrr))
  1520.                         return;
  1521.  
  1522.             // we must take the focus away so we don't send bogus mouse events
  1523.  
  1524.                 (*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
  1525.  
  1526.             // the mouse is pointing to something else. try to find it
  1527.  
  1528.                 o = CurrList->head;
  1529.                 while (o) {
  1530.  
  1531.                     if (PtInRect ((point *)&e->vpos,&o->scrr) ||
  1532.                         PtInRect ((point *)&e->vpos,&o->swir)) {
  1533.  
  1534.                         // focus given if the object takes mouse events
  1535.  
  1536.                         CurrentObject = o;
  1537.                         (*o->scr) (FOCUS_GIVEN,o);
  1538.                         break;
  1539.  
  1540.                     }
  1541.                     o = o->next;
  1542.                 }
  1543.         }
  1544. #endif
  1545. }
  1546.  
  1547.  
  1548.     /*\
  1549.     |*|----====< void DrawScreen (rect *, char *argv[]) >====----
  1550.     |*|
  1551.     |*| Perform the screen draw for this screen
  1552.     |*|
  1553.     |*| Entry Conditions:
  1554.     |*|     2 parms
  1555.     |*|
  1556.     |*| Exit Conditions:
  1557.     |*|     None
  1558.     |*|
  1559.     \*/
  1560. static void DrawScreen (r,txt)
  1561.     rect *r;
  1562.     char *txt[];
  1563. {
  1564. rect wr;
  1565. int x;
  1566.  
  1567.     // inner box color
  1568.  
  1569.         wr.row1 = r->row1;
  1570.         wr.row2 = r->row2;
  1571.         wr.col1 = r->col1;
  1572.         wr.col2 = r->col2-2;
  1573.         _videoattr (Colors->BkGn_AND,Colors->BkGn_XOR,&wr);
  1574.  
  1575.     // vertical right side shadow
  1576.  
  1577.         wr.row1 = r->row1+1;
  1578.         wr.row2 = r->row2+1;
  1579.         wr.col1 = r->col2-1;
  1580.         wr.col2 = r->col2+0;
  1581.         _videoattr (Colors->Shdw_AND,Colors->Shdw_XOR,&wr);
  1582.  
  1583.     // horizontal bottom shadow
  1584.  
  1585.         wr.row1 = wr.row2;
  1586.         wr.col1 = r->col1+2;
  1587.         _videoattr (Colors->Shdw_AND,Colors->Shdw_XOR,&wr);
  1588.  
  1589.     // actual text
  1590.  
  1591.         if (txt) {
  1592.             for (x=r->row1;x<=r->row2;x++) {
  1593.                 _videosetcurs (x,r->col1);
  1594.                 _zipout (txt[x-r->row1],0);
  1595.             }
  1596.         }
  1597.  
  1598.     // change some attributes on the color screen
  1599.  
  1600.         if (VideoSegment == 0xb800)
  1601.             ChangeAttributes (r->row1, r->col1, r->row2, r->col2-2);
  1602. }
  1603.  
  1604.  
  1605.     /*\
  1606.     |*|----====< PaintScreen (int,int) >====----
  1607.     |*|
  1608.     |*| Draw/Restore the screen
  1609.     |*|
  1610.     |*| Entry Conditions:
  1611.     |*|     INT is a TRUE/FALSE flag
  1612.     |*|     INT is a WIPE or DISSOLVE to original flag
  1613.     |*|
  1614.     |*| Exit Conditions:
  1615.     |*|     None
  1616.     |*|
  1617.     \*/
  1618. static void PaintScreen (tf,fl)
  1619.     int tf;
  1620.     int fl;
  1621. {
  1622. rect r;
  1623.  
  1624. static int backedup = FALSE;
  1625.  
  1626.     if (tf) {            // paint the screen
  1627.  
  1628.         if (!backedup)
  1629.             BackupVideo ( &OurWnd.wndr, (char far *)&screenbuffer[0], 0, 0 );
  1630.  
  1631.         backedup = TRUE;
  1632.  
  1633.         if (CallersFillChar)
  1634.             _videofill ( CallersFillChar, Colors->Filler, &OurWnd.wndr );
  1635.  
  1636.         DrawScreen ( &MixerRect,  &screenlayout[0] );
  1637.         r.row2 = r.row1 = MixerRect.row1+1;
  1638.         r.col1 = MixerRect.col1+1;
  1639.         r.col2 = MixerRect.col2-3;
  1640.         _videoattr ( Colors->ButHi_AND, Colors->ButHi_XOR,&r);
  1641.  
  1642.         DrawScreen ( &RecordRect, &screen3[0] );
  1643.         DrawScreen ( &VolRect,      &screen2[0] );
  1644.         DrawScreen ( &Help2Rect,  &screen4[0] );
  1645.  
  1646.     }
  1647.  
  1648.     else {
  1649.  
  1650.         if (backedup) {
  1651.  
  1652.             if (fl)
  1653.                 dissolve (25,80,(char far *)&screenbuffer[0]);
  1654.             else
  1655.                 RestoreVideo ( &OurWnd.wndr, (char far *) &screenbuffer[0], 0, 0 );
  1656.  
  1657.             backedup = FALSE;
  1658.         }
  1659.     }
  1660. }
  1661.  
  1662.  
  1663.     /*\
  1664.     |*|----====< ProcessRecordEffects (int) >====----
  1665.     |*|
  1666.     |*| Process the Effects dialog box
  1667.     |*|
  1668.     |*| Entry Conditions:
  1669.     |*|     None
  1670.     |*|
  1671.     |*| Exit Conditions:
  1672.     |*|     None
  1673.     |*|
  1674.     \*/
  1675. static void ProcessRecordEffects(msg)
  1676.     int msg;
  1677. {
  1678. rect r;
  1679.  
  1680. static void *ol;
  1681. static void *effectslastobj;
  1682. static void *effectscurrobj;
  1683.  
  1684.         switch (msg) {
  1685.  
  1686.             case DRAWIT:
  1687.                 DrawScreen ( &EffectsRect, &effectsbkgn[0] );
  1688.                 DrawScreen ( &Screen6Rect, &screen6[0]       );
  1689.                 DrawScreen ( &Screen5Rect, &screen5[0]       );
  1690.                 DrawScreen ( &Screen7Rect, &screen7[0]       );
  1691.                 BroadcastToList (DRAWIT,CurrList);    // draw the controls
  1692.                 break;
  1693.  
  1694.             case FOCUS_GIVEN:
  1695.  
  1696.                 // let the current object know its not in foreground
  1697.  
  1698.                     (*CurrentObject->scr)(FOCUS_TAKEN,CurrentObject);
  1699.  
  1700.                 // switch linked lists and current objects
  1701.  
  1702.                     ol = CurrList;                    // switch object lists
  1703.                     CurrList = &EffectsList;
  1704.  
  1705.                     effectslastobj = CurrentObject; // switch objects
  1706.                     if ((CurrentObject = effectscurrobj) == 0)
  1707.                         CurrentObject = CurrList->head;
  1708.  
  1709.                 // paint the screen
  1710.  
  1711.                     ProcessRecordEffects(DRAWIT);
  1712.  
  1713.                     (*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // highlight
  1714.  
  1715.                 // all done till a FOCUS_TAKEN is received
  1716.  
  1717.                     break;
  1718.  
  1719.             case FOCUS_TAKEN:
  1720.  
  1721.                 // let the current object know its not in foreground
  1722.  
  1723.                     (*CurrentObject->scr)(FOCUS_TAKEN,CurrentObject);
  1724.  
  1725.                 // switch linked lists and current objects
  1726.  
  1727.                     CurrList = ol;                    // restore the old list
  1728.  
  1729.                     effectscurrobj = CurrentObject; // switch objects
  1730.                     if (effectslastobj)
  1731.                         CurrentObject  = effectslastobj;
  1732.  
  1733.                 // restore the screen
  1734.  
  1735.                     PaintScreen     (FALSE,FALSE);        // restore the screen
  1736.                     PaintScreen     (TRUE,FALSE);        // put up the screen
  1737.                     BroadcastToList (DRAWIT,CurrList);    // draw the controls
  1738.  
  1739.                     (*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // highlight
  1740.  
  1741.                     break;
  1742.  
  1743.                 default:
  1744.                     break;
  1745.  
  1746.             }
  1747. }
  1748.  
  1749.  
  1750.  
  1751.     /*\
  1752.     |*|----====< PtInRect (point *, rect *) >====----
  1753.     |*|
  1754.     |*| return TRUE if point is within the rectangle
  1755.     |*|
  1756.     |*| Entry Conditions:
  1757.     |*|     None
  1758.     |*|
  1759.     |*| Exit Conditions:
  1760.     |*|     None
  1761.     |*|
  1762.     \*/
  1763. static int PtInRect (p,r)
  1764.     point *p;
  1765.     rect  *r;
  1766. {
  1767.  
  1768.     if ((p->row < r->row1) && (p->row >= r->row2))
  1769.         return(FALSE);
  1770.     if ((p->col < r->col1) && (p->col >= r->col2))
  1771.         return(FALSE);
  1772.  
  1773.     return (TRUE);
  1774. }
  1775.  
  1776.  
  1777.     /*\
  1778.     |*|----====< int ScrollObjectHandler() >====----
  1779.     |*|
  1780.     |*| Scroll bar object control
  1781.     |*|
  1782.     |*| Entry Conditions:
  1783.     |*|     None
  1784.     |*|
  1785.     |*| Exit Conditions:
  1786.     |*|     None
  1787.     |*|
  1788.     \*/
  1789. static int ScrollObjectHandler (msg,o,ptr)
  1790.     int msg;
  1791.     SPtr o;
  1792.     void *ptr;
  1793. {
  1794. void **pptr;
  1795. rect r;
  1796. int l,ri,i,key;
  1797. char c1,c2;
  1798.  
  1799.     // get a pointer to the stack
  1800.  
  1801.         pptr = &ptr;
  1802.  
  1803.     // process the message
  1804.  
  1805.         switch (msg) {
  1806.  
  1807.             case OPEVENT:
  1808.  
  1809.                 key = 0;
  1810.  
  1811.                 switch (((EPtr)pptr[0])->buttons) {
  1812.  
  1813.                     case ENDKEY:                // right = 2;
  1814.                         key++;
  1815.                     case HOMEKEY:                // left  = 1;
  1816.                         key++;
  1817.                     case LFARROW:                // both  = 0;
  1818.  
  1819.                         if (key != 2) {         // do LEFT on left/both cases
  1820.  
  1821.                             if (o->leftchannel > 0)
  1822.                                 o->leftchannel -= 3;
  1823.  
  1824.                             SendMixer
  1825.                               (
  1826.                                 "SET ",
  1827.                                 o->mixerselect,
  1828.                                 1,
  1829.                                 o,
  1830.                                 BI_SETTO,
  1831.                                 o->leftchannel
  1832.                               );
  1833.  
  1834.                         }
  1835.  
  1836.                         if (key != 1) {         // do RIGHT on right/both cases
  1837.  
  1838.                             if (o->ritchannel > 0)
  1839.                                 o->ritchannel -= 3;
  1840.  
  1841.                             SendMixer
  1842.                               (
  1843.                                 "SET ",
  1844.                                 o->mixerselect,
  1845.                                 2,
  1846.                                 o,
  1847.                                 BI_SETTO,
  1848.                                 o->ritchannel
  1849.                               );
  1850.  
  1851.                         }
  1852.  
  1853.                         (*o->scr) (DRAWIT,o);
  1854.  
  1855.                         break;
  1856.  
  1857.                     case PGDNKEY:                // right = 2;
  1858.                         key++;
  1859.                     case PGUPKEY:               // left  = 1;
  1860.                         key++;
  1861.                     case RIARROW:                // both  = 0;
  1862.  
  1863.                         if (key != 2) {         // do LEFT on left/both cases
  1864.  
  1865.                             if (o->leftchannel < 100)
  1866.                                 o->leftchannel += 3;
  1867.  
  1868.                             SendMixer
  1869.                               (
  1870.                                 "SET ",
  1871.                                 o->mixerselect,
  1872.                                 1,
  1873.                                 o,
  1874.                                 BI_SETTO,
  1875.                                 o->leftchannel
  1876.                               );
  1877.                         }
  1878.  
  1879.                         if (key != 1) {         // do RIGHT on right/both cases
  1880.  
  1881.                             if (o->ritchannel < 100)
  1882.                                 o->ritchannel += 3;
  1883.  
  1884.                             SendMixer
  1885.                               (
  1886.                                 "SET ",
  1887.                                 o->mixerselect,
  1888.                                 2,
  1889.                                 o,
  1890.                                 BI_SETTO,
  1891.                                 o->ritchannel
  1892.                               );
  1893.                         }
  1894.  
  1895.                         (*o->scr) (DRAWIT,o);
  1896.  
  1897.                         break;
  1898.  
  1899.                     default:
  1900.                         break;
  1901.                 }
  1902.  
  1903.                 break;
  1904.  
  1905.             case SENDIT:
  1906.  
  1907.                 SendMixer ("SET ",o->mixerselect,1,o,BI_SETTO,o->leftchannel);
  1908.                 (*(void(*)())ptr)(&CommandString);
  1909.                 SendMixer ("SET ",o->mixerselect,2,o,BI_SETTO,o->ritchannel);
  1910.                 (*(void(*)())ptr)(&CommandString);
  1911.                 break;
  1912.  
  1913.             case FOCUS_GIVEN:
  1914.  
  1915.                 // highlight the entire field
  1916.  
  1917.                     r.row1 = o->namr.row1;
  1918.                     r.row2 = o->namr.row2;
  1919.                     r.col2 = r.col1 = o->namr.col2+2;
  1920.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  1921.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  1922.  
  1923.                     r.row1 = o->scrr.row1;
  1924.                     r.row2 = o->scrr.row2;
  1925.                     r.col2 = r.col1 = o->scrr.col2+2;
  1926.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  1927.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  1928.  
  1929.                     if (o->swi)
  1930.                         _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->swir );
  1931.  
  1932.                     break;
  1933.  
  1934.             case FOCUS_TAKEN:
  1935.  
  1936.                 // highlight the entire field
  1937.  
  1938.                     r.row1 = o->namr.row1;
  1939.                     r.row2 = o->namr.row2;
  1940.                     r.col2 = r.col1 = o->namr.col2+2;
  1941.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  1942.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1943.  
  1944.                     r.row1 = o->scrr.row1;
  1945.                     r.row2 = o->scrr.row2;
  1946.                     r.col2 = r.col1 = o->scrr.col2+2;
  1947.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  1948.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  1949.  
  1950.                     if (o->swi)
  1951.                         _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->swir );
  1952.  
  1953.                     break;
  1954.  
  1955.             case DRAWIT:
  1956.  
  1957.                 // move the cursor to the slide bar area
  1958.  
  1959.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  1960.                     _zipout       ( twobar, 0);
  1961.                     _videosetcurs ( o->scrr.row1+1, o->scrr.col1 );
  1962.                     _zipout       ( twobar, 0);
  1963.  
  1964.                     l = (o->leftchannel * 31) / 100;
  1965.                     _videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
  1966.                     _zipout (((l & 1) ? "fi" : "›"), 0);
  1967.                     l = (o->ritchannel * 31) / 100;
  1968.                     _videosetcurs ( o->scrr.row1+1, o->scrr.col1+(l>>1) );
  1969.                     _zipout (((l & 1) ? "fi" : "›"), 0);
  1970.  
  1971.                 // display a mixer bar
  1972.  
  1973.                     if (o->swi) {
  1974.  
  1975.                       //if (o->mixerselect == BI_INPUTMIXER)
  1976.                       //    _videoattr (Colors->ButHi_AND,Colors->ButHi_XOR,&o->swir);
  1977.                       //else
  1978.                       //    _videoattr (Colors->ButLo_AND,Colors->ButLo_XOR,&o->swir);
  1979.  
  1980.                         if (o->mixerselect == BI_INPUTMIXER) {
  1981.                             _videosetcurs (o->swir.row1,o->swir.col1);
  1982.                             _zipout (playmsgi1);
  1983.                             _videosetcurs (o->swir.row1+1,o->swir.col1);
  1984.                             _zipout (playmsgi2);
  1985.                         }
  1986.                         else {
  1987.                             _videosetcurs (o->swir.row1,o->swir.col1);
  1988.                             _zipout (playmsgo1);
  1989.                             _videosetcurs (o->swir.row1+1,o->swir.col1);
  1990.                             _zipout (playmsgo2);
  1991.                         }
  1992.                     }
  1993.  
  1994.                 break;
  1995.  
  1996.             case OPENINIT:
  1997.  
  1998.                 // get the output mixer current state
  1999.  
  2000.                 SendMixer ("GET ",BI_OUTPUTMIXER,0,o,0,0);
  2001.                 DecodeMixer (MVResponse);
  2002.  
  2003.                 if (leftswitch == '+') {
  2004.                     o->mixerselect    = BI_OUTPUTMIXER;
  2005.                     o->leftchannel    = leftvolume;
  2006.                 }
  2007.                 else {
  2008.                     o->deadmixer    = BI_OUTPUTMIXER;
  2009.                     o->deadlchannel = leftvolume;
  2010.                 }
  2011.  
  2012.                 if (ritswitch == '+') {
  2013.                     o->mixerselect    = BI_OUTPUTMIXER;
  2014.                     o->ritchannel    = ritvolume;
  2015.                 }
  2016.                 else {
  2017.                     o->deadmixer    = BI_OUTPUTMIXER;
  2018.                     o->deadrchannel = ritvolume;
  2019.                 }
  2020.  
  2021.                 // get the input mixer current state
  2022.  
  2023.                 SendMixer ("GET ",BI_INPUTMIXER,0,o,0,0);
  2024.                 DecodeMixer (MVResponse);
  2025.  
  2026.                 if (leftswitch == '+') {
  2027.                     o->mixerselect    = BI_INPUTMIXER;
  2028.                     o->leftchannel    = leftvolume;
  2029.                 }
  2030.                 else {
  2031.                     o->deadmixer    = BI_INPUTMIXER;
  2032.                     o->deadlchannel = leftvolume;
  2033.                 }
  2034.  
  2035.                 if (ritswitch == '+') {
  2036.                     o->mixerselect    = BI_INPUTMIXER;
  2037.                     o->ritchannel    = ritvolume;
  2038.                 }
  2039.                 else {
  2040.                     o->deadmixer    = BI_INPUTMIXER;
  2041.                     o->deadrchannel = ritvolume;
  2042.                 }
  2043.  
  2044.                 // make sure both inputs are on the same mixer
  2045.  
  2046.                 SendMixer ("SET ",o->mixerselect,1,o,BI_SETTO,o->leftchannel);
  2047.                 SendMixer ("SET ",o->mixerselect,2,o,BI_SETTO,o->ritchannel);
  2048.                 break;
  2049.  
  2050.             case CLEARIT:
  2051.                 break;
  2052.  
  2053.             default:
  2054.                 break;
  2055.         }
  2056. }
  2057.  
  2058.  
  2059.     /*\
  2060.     |*|----====< int SendOnOff( char *, char *, int, VPtr, int, int ) >====----
  2061.     |*|
  2062.     |*| Send a mixer selection
  2063.     |*|
  2064.     |*| Entry Conditions:
  2065.     |*|     char *cmd = "SET", "GET"
  2066.     |*|     VPtr o      = Volume device name
  2067.     |*|     int  v      = new volume setting
  2068.     |*|
  2069.     |*| Exit Conditions:
  2070.     |*|     MVResponse string holds the result
  2071.     |*|
  2072.     \*/
  2073. static int SendOnOff(cmd,dev,o)
  2074.     char *cmd;    // command
  2075.     char *dev;    // device
  2076.     BPtr o;     // channel name & state
  2077.  
  2078. {
  2079.  
  2080.     // build the string
  2081.  
  2082.         strcpy (CommandString,cmd);        // command
  2083.         strcat (CommandString,dev);        // device name
  2084.         strcat (CommandString,o->name);    // input channel
  2085.         strcat (CommandString,((o->state) ? "ON" : "OFF"));
  2086.  
  2087.         SendTextOut (CommandString);
  2088. }
  2089.  
  2090.  
  2091.     /*\
  2092.     |*|----====< int SendMixer( char *, int, int, SPtr, int, int ) >====----
  2093.     |*|
  2094.     |*| Send a mixer selection
  2095.     |*|
  2096.     |*|     char *cmd = "SET", "GET"
  2097.     |*|     int  dev  = INPUTMIXER or OUTPUTMIXER
  2098.     |*|     int  lr   = both(0),left(1),right(2)
  2099.     |*|     VPtr o      = Volume device name
  2100.     |*|     int  f      = function (UP/DOWN/TO)
  2101.     |*|     int  v      = new volume setting
  2102.     |*|
  2103.     |*| Exit Conditions:
  2104.     |*|     MVResponse string holds the result
  2105.     |*|
  2106.     \*/
  2107. static int SendMixer (cmd,dev,lr,o,f,v)
  2108.     char *cmd;    // command
  2109.     int dev;    // device name
  2110.     int lr;     // left/right/both
  2111.     SPtr o;     // input channel name
  2112.     int f;        // movement function
  2113.     int v;        // new mixer value
  2114.  
  2115. {
  2116. char *fs,*ms,*lrs;
  2117. char val[7];
  2118.  
  2119.     // get the text string equvalent for the function
  2120.  
  2121.         switch (lr) {
  2122.  
  2123.             case 1:
  2124.                 lrs = "LEFT ";  // LEFT side only
  2125.                 break;
  2126.  
  2127.             case 2:
  2128.                 lrs = "RIGHT "; // RIGHT side only
  2129.                 break;
  2130.  
  2131.             case 0:             // BOTH
  2132.             default:
  2133.                 lrs = makemenull;
  2134.                 break;
  2135.         }
  2136.  
  2137.     // get the text string equvalent for the function
  2138.  
  2139.         switch (f) {
  2140.             case BI_SETTO:
  2141.                 fs = "TO ";
  2142.                 break;
  2143.  
  2144.             case BI_UPTO:
  2145.                 fs = "UP ";
  2146.                 break;
  2147.  
  2148.             case BI_DOWNTO:
  2149.                 fs = "DOWN ";
  2150.                 break;
  2151.  
  2152.             default:
  2153.                 fs = makemenull;
  2154.                 break;
  2155.         }
  2156.  
  2157.     // correct the value
  2158.  
  2159.         if (v < 0)     v = 0;
  2160.         if (v > 100) v = 100;
  2161.  
  2162.     // build the string
  2163.  
  2164.         ms = (dev == BI_OUTPUTMIXER) ? "OUTPUT MIXER " : "INPUT MIXER ";
  2165.         itoa   (v,val,10);
  2166.  
  2167.         strcpy (CommandString,cmd);          // command
  2168.         strcat (CommandString,ms);             // device name
  2169.         strcat (CommandString,lrs);          // left/right
  2170.         strcat (CommandString,o->name);      // input channel
  2171.         strcat (CommandString,fs);             // function (up/down/to)
  2172.         strcat (CommandString,val);          // new #
  2173.         strcat (CommandString," PERCENT");
  2174.  
  2175.         SendTextOut (CommandString);
  2176. }
  2177.  
  2178.  
  2179.     /*\
  2180.     |*|----====< int SendVolume( char *, int, VPtr, int, int ) >====----
  2181.     |*|
  2182.     |*| Send a mixer selection
  2183.     |*|
  2184.     |*| Entry Conditions:
  2185.     |*|     char *cmd = "SET", "GET"
  2186.     |*|     int  lr   = both(0),left(1),right(2)
  2187.     |*|     VPtr o      = Volume device name
  2188.     |*|     int  f      = function (UP/DOWN/TO)
  2189.     |*|     int  v      = new volume setting
  2190.     |*|
  2191.     |*| Exit Conditions:
  2192.     |*|     MVResponse string holds the result
  2193.     |*|
  2194.     \*/
  2195. static int SendVolume (cmd,lr,o,f,v)
  2196.     char *cmd;    // command
  2197.     int lr;     // left/right/both
  2198.     VPtr o;     // channel name
  2199.     int f;        // movement function
  2200.     int v;        // new mixer value
  2201.  
  2202. {
  2203. char *fs,*ms,*lrs;
  2204. char val[7];
  2205.  
  2206.     // get the text string equvalent for the function
  2207.  
  2208.         switch (lr) {
  2209.  
  2210.             case 1:
  2211.                 lrs = "LEFT ";  // LEFT side only
  2212.                 break;
  2213.  
  2214.             case 2:
  2215.                 lrs = "RIGHT "; // RIGHT side only
  2216.                 break;
  2217.  
  2218.             case 0:             // BOTH
  2219.             default:
  2220.                 lrs = makemenull;
  2221.                 break;
  2222.         }
  2223.  
  2224.     // get the text string equvalent for the function
  2225.  
  2226.         switch (f) {
  2227.             case BI_SETTO:
  2228.                 fs = "TO ";
  2229.                 break;
  2230.  
  2231.             case BI_UPTO:
  2232.                 fs = "UP ";
  2233.                 break;
  2234.  
  2235.             case BI_DOWNTO:
  2236.                 fs = "DOWN ";
  2237.                 break;
  2238.  
  2239.             default:
  2240.                 fs = makemenull;
  2241.                 break;
  2242.         }
  2243.  
  2244.     // correct the value on slide bars
  2245.  
  2246.         if (o->type == OBJ_VOLUME) {
  2247.  
  2248.             // fudge the volume to correct the rounding errors
  2249.  
  2250.             if (++v < 0)   v = 0;
  2251.             if (v > 100) v = 100;
  2252.         }
  2253.  
  2254.     // build the string
  2255.  
  2256.         itoa   (v,val,10);
  2257.  
  2258.         strcpy (CommandString,cmd);          // command
  2259.         strcat (CommandString,"VOLUME ");    // device name
  2260.         strcat (CommandString,lrs);          // left/right
  2261.         strcat (CommandString,o->name);      // input channel
  2262.         strcat (CommandString,fs);             // function (up/down/to)
  2263.  
  2264.         if (o->type == OBJ_VOLUME) {
  2265.             strcat (CommandString,val);      // new #
  2266.             strcat (CommandString," PERCENT");
  2267.         }
  2268.         else
  2269.             strcat (CommandString,((v) ? "ON" : "OFF"));
  2270.  
  2271.         SendTextOut (CommandString);
  2272. }
  2273.  
  2274.  
  2275.     /*\
  2276.     |*|----====< int SendTextOut( char * ) >====----
  2277.     |*|
  2278.     |*| Send a text string to MVPROAS
  2279.     |*|
  2280.     |*| Entry Conditions:
  2281.     |*|     None
  2282.     |*|
  2283.     |*| Exit Conditions:
  2284.     |*|     None
  2285.     |*|
  2286.     \*/
  2287. static int SendTextOut(s)
  2288.     char *s;
  2289. {
  2290. char *b;
  2291.  
  2292.         b = s;
  2293.         while (*b++) ;
  2294.         write (mv,s,b-s);
  2295.  
  2296.         _dlgflushfile(mv);    // the below code is now in dialoga.asm
  2297.         //    _asm {
  2298.         //        mov     bx,mv
  2299.         //        mov     ah,45h
  2300.         //        int     21h
  2301.         //        jnc     thisisbad
  2302.         //        mov     bx,ax
  2303.         //        mov     ah,3eh
  2304.         //        int     21h
  2305.         //    thisisbad:
  2306.         //    }
  2307.  
  2308.        read (mv,MVResponse,80);
  2309.  
  2310.             {
  2311.             char *m= MVResponse;
  2312.  
  2313.             do
  2314.                 if (*m == '\n')
  2315.                     *m= ' ';
  2316.             while (*++m);
  2317.             do
  2318.                 if (*m == ' ')
  2319.                     *m--= '\0';
  2320.                 else
  2321.                     m--;
  2322.             while (isspace(*m));
  2323.             }
  2324.  
  2325. }
  2326.  
  2327.  
  2328.     /*\
  2329.     |*|----====< int SwitchObjectHandler() >====----
  2330.     |*|
  2331.     |*| mixer selection switch object control
  2332.     |*|
  2333.     |*| Entry Conditions:
  2334.     |*|     None
  2335.     |*|
  2336.     |*| Exit Conditions:
  2337.     |*|     None
  2338.     |*|
  2339.     \*/
  2340.  
  2341. static int SwitchObjectHandler(msg,o,ptr)
  2342.     int msg;
  2343.     SPtr o;
  2344.     void *ptr;
  2345. {
  2346. void **pptr;
  2347.  
  2348.     // get a pointer to the stack
  2349.  
  2350.         pptr = &ptr;
  2351.  
  2352.     // process the message
  2353.  
  2354.         switch (msg) {
  2355.  
  2356.             case OPEVENT:
  2357.  
  2358.                 switch (((EPtr)pptr[0])->buttons) {
  2359.  
  2360.                     case ENTER:
  2361.  
  2362.                         // toggle the input/output mixer selection
  2363.  
  2364.                         if (o == &DigitalScroll)
  2365.                             break;
  2366.  
  2367.                         if (o->mixerselect == BI_OUTPUTMIXER)
  2368.                             o->mixerselect = BI_INPUTMIXER;
  2369.                         else
  2370.                             o->mixerselect = BI_OUTPUTMIXER;
  2371.  
  2372.                         SendMixer
  2373.                           (
  2374.                             "SET ",
  2375.                             o->mixerselect,
  2376.                             1,
  2377.                             o,
  2378.                             BI_SETTO,
  2379.                             o->leftchannel
  2380.                           );
  2381.  
  2382.                         SendMixer
  2383.                           (
  2384.                             "SET ",
  2385.                             o->mixerselect,
  2386.                             2,
  2387.                             o,
  2388.                             BI_SETTO,
  2389.                             o->ritchannel
  2390.                           );
  2391.  
  2392.                         (*o->scr) (DRAWIT,o);
  2393.  
  2394.                     default:
  2395.                         break;
  2396.                 }
  2397.                 break;
  2398.  
  2399.             case SENDIT:
  2400.             case FOCUS_GIVEN:
  2401.             case FOCUS_TAKEN:
  2402.             case DRAWIT:
  2403.             case CLEARIT:
  2404.             case OPENINIT:
  2405.             default:
  2406.                 break;
  2407.         }
  2408. }
  2409.  
  2410.  
  2411.  
  2412.     /*\
  2413.     |*|----====< int  SystemKey(EPtr); >====----
  2414.     |*|
  2415.     |*|    Check the event for a system keystroke.
  2416.     |*|
  2417.     \*/
  2418. static int    SystemKey(e)
  2419.     EPtr e;
  2420. {
  2421. Event ev;
  2422. rect r;
  2423. OLPtr ol;
  2424.  
  2425.     // exit if not a keyboard event
  2426.  
  2427.         if (e->type != EV_KEYB)
  2428.             return(0);
  2429.  
  2430.     // process it...
  2431.  
  2432.         switch (e->buttons) {
  2433.  
  2434.             case ESCAPE:
  2435.  
  2436.                 if (DialogBox & EFFECTS_DLG) {
  2437.                     ProcessRecordEffects(FOCUS_TAKEN);
  2438.                     DialogBox &= ~EFFECTS_DLG;
  2439.                 }
  2440.                 else
  2441.                     exitcode = TRUE;
  2442.  
  2443.                 return(1);
  2444.  
  2445.             case ENTER:
  2446.                 if (CurrentObject->type == OBJ_SCROLL) {
  2447.                     if (CurrentObject->swi)
  2448.                         (*CurrentObject->swi) (OPEVENT,CurrentObject,e);
  2449.                 }
  2450.                 else
  2451.                     (*CurrentObject->scr) (OPEVENT,CurrentObject,e);
  2452.                 return(1);
  2453.  
  2454.             case HOMEKEY:
  2455.             case PGDNKEY:
  2456.             case ENDKEY:
  2457.             case PGUPKEY:
  2458.             case PLUSKEY1:
  2459.             case PLUSKEY2:
  2460.             case MINUSKEY1:
  2461.             case MINUSKEY2:
  2462.             case RIARROW:
  2463.             case LFARROW:
  2464.                 (*CurrentObject->scr) (OPEVENT,CurrentObject,e);
  2465.                 return(1);
  2466.  
  2467.             case SH_TABKEY:
  2468.             case UPARROW:
  2469.  
  2470.                 (*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
  2471.  
  2472.                 if (CurrentObject->back)
  2473.                     CurrentObject = CurrentObject->back;
  2474.                 else
  2475.                     CurrentObject = CurrList->tail;
  2476.  
  2477.                 (*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
  2478.                 return(TRUE);
  2479.  
  2480.             case TABKEY:
  2481.             case DNARROW:
  2482.  
  2483.                 (*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
  2484.  
  2485.                 if (CurrentObject->next)
  2486.                     CurrentObject = CurrentObject->next;
  2487.                 else
  2488.                     CurrentObject = CurrList->head;
  2489.  
  2490.                 (*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
  2491.                 return(TRUE);
  2492.  
  2493.             case F1KEY:
  2494.  
  2495.                 // draw the help screen
  2496.  
  2497.                     if (VideoSegment == 0xb800)
  2498.                         Colors = &HelpsColorScheme;
  2499.  
  2500.                     DrawScreen    ( &Help1Rect, &helpscreen[0] );
  2501.  
  2502.                 // do some special highlighting for enhanced looks
  2503.  
  2504.                     if (VideoSegment == 0xb800) {
  2505.  
  2506.                         r.row2 = ( r.row1 = Help1Rect.row1 + 1) + 1;
  2507.                         r.col1 = Help1Rect.col1 + 1;
  2508.                         r.col2 = Help1Rect.col2 - 3;
  2509.  
  2510.                         _videoattr
  2511.                           (
  2512.                             0x00,
  2513.                             0x3f,
  2514.                             &r
  2515.                           );
  2516.                     }
  2517.  
  2518.                 // wait for a keystroke
  2519.  
  2520.                     while (!GetEvent (&ev))  ;
  2521.  
  2522.                     if (VideoSegment == 0xb800)
  2523.                         Colors = &ColorScheme;
  2524.  
  2525.                 // restore the screen
  2526.  
  2527.                     PaintScreen  (FALSE,FALSE);     // restore the screen
  2528.                     PaintScreen  (TRUE,FALSE);        // put up the screen
  2529.                     BroadcastToList (DRAWIT,&MainList); // draw the controls
  2530.  
  2531.                     if (DialogBox & EFFECTS_DLG) {
  2532.                         ProcessRecordEffects(DRAWIT);
  2533.                         BroadcastToList (DRAWIT,&EffectsList);
  2534.                     }
  2535.  
  2536.                     (*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // re-highlight
  2537.                     return(TRUE);
  2538.  
  2539.             case F2KEY:
  2540.  
  2541.                 // try to open and process the effects windows
  2542.  
  2543.                     if (!(DialogBox & EFFECTS_DLG)) {
  2544.  
  2545.                         // do not re-enter
  2546.  
  2547.                             DialogBox |= EFFECTS_DLG;
  2548.  
  2549.                             ProcessRecordEffects(FOCUS_GIVEN);
  2550.                     }
  2551.                     return(TRUE);
  2552.  
  2553.             case F5KEY:    /* F5-F8 load mixer settings from DOS file */
  2554.             case F6KEY: /* subtract F5 scancode from key pressed */
  2555.             case F7KEY: /* move high byte to low and use as index (0-3) */
  2556.             case F8KEY:
  2557.                 loadcurrent((e->buttons- F5KEY)>> 8);    /* open, read setting[0-3].pas and SendTextOut */
  2558.                 BroadcastMsg (OPENINIT); // tell everyone we are starting
  2559.                 BroadcastToList (DRAWIT,CurrList);     // draw the controls
  2560.                 return(TRUE);
  2561.  
  2562.             case SF5KEY: /* Shift F5-F8 save mixer settings into DOS file */
  2563.             case SF6KEY: /* subtract SF5 scancode from key pressed */
  2564.             case SF7KEY: /* move high byte to load and use as index (0-3) */
  2565.             case SF8KEY:
  2566.                 savecurrent((e->buttons- SF5KEY)>> 8); /* save setting[0-3].pas */
  2567.                 return(TRUE);
  2568.  
  2569.             case F4KEY:
  2570.  
  2571.                 // have all objects re-init themselves, then redraw
  2572.  
  2573.                     SendTextOut  ("RESET");  // reset the mixers
  2574.                     BroadcastMsg (OPENINIT); // tell everyone we are starting
  2575.                     BroadcastToList (DRAWIT,CurrList);     // draw the controls
  2576.                     return(TRUE);
  2577.  
  2578.             default:
  2579.                 return(FALSE);
  2580.         }
  2581.  
  2582. }
  2583.  
  2584.  
  2585.     /*\
  2586.     |*|----====< void SystemShutDown(); >====----
  2587.     |*|
  2588.     |*|    Exits to the swapper to exit for good, or loads a program.
  2589.     |*|
  2590.     \*/
  2591. static void SystemShutDown()
  2592. {
  2593.    //    MouseInit        ( OFF,OFF );            // kill the mouse
  2594.  
  2595.    // restore the video
  2596.  
  2597.         PaintScreen   ( FALSE,TRUE );        // take down the screen
  2598.         _videosetcurs ( OrigRow, OrigCol ); // restore the cursor position
  2599.         _videocshape  ( -1, -1);            // now, restore the original shape
  2600.  
  2601.     // restore numlock
  2602.  
  2603.         _dlgrestorenumlock();    // the below code is now in dialoga.asm
  2604.         //    _asm {
  2605.         //        push    es                        ; save the numlock state
  2606.         //        sub     ax,ax
  2607.         //        mov     es,ax
  2608.         //        mov     al,NumLockState
  2609.         //        or        es:[0x417],al            ; possibly set it
  2610.         //        pop     es
  2611.         //    }
  2612. }
  2613.  
  2614.  
  2615.     /*\
  2616.     |*|----====< void SystemInit() >====----
  2617.     |*|
  2618.     |*| System wide initialization of the program
  2619.     |*|
  2620.     |*| Entry Conditions:
  2621.     |*|     None
  2622.     |*|
  2623.     |*| Exit Conditions:
  2624.     |*|     None
  2625.     |*|
  2626.     \*/
  2627. static int SystemInit()
  2628. {
  2629. int n;
  2630. long l;
  2631.  
  2632.     /* setup the mouse & move to the middle of the wave window          */
  2633.  
  2634.     //    MouseInit    (ON,OFF);
  2635.     //    MouseAction (0x12);             // left button down/up action
  2636.  
  2637.         if (_videocard() == 1) {        // if mono, point to that segment
  2638.             VideoSegment = OurWnd.sseg = 0xb000;
  2639.             Colors = &MonoScheme;
  2640.         }
  2641.  
  2642.     // get the original row, column and kill numlock
  2643.  
  2644.  
  2645.         l = _videogetcurs();
  2646.         OrigCol = (int) (l >> 16) & 0xffff;
  2647.         OrigRow = (int) l & 0xffff;
  2648.  
  2649.         _dlgsavenumlock();        // the below code is now in dialoga.asm
  2650.         //    _asm {
  2651.         //        push    es                            ; save the numlock state
  2652.         //        sub     ax,ax
  2653.         //        mov     es,ax
  2654.         //        mov     al,0x20
  2655.         //        and     al,es:[0x417]
  2656.         //        and     byte ptr es:[0x417],0xdf    ; clear it...
  2657.         //        mov     NumLockState,al
  2658.         //        pop     es
  2659.         //    }
  2660.  
  2661.     // turn off the cursor
  2662.  
  2663.         _videocshape (0,0x20);            // make it invisible
  2664.  
  2665.     /* init all objects, then paint them on the screen                    */
  2666.  
  2667.         BroadcastMsg (OPENINIT);        // tell everyone we are starting
  2668.  
  2669.         PaintScreen  (TRUE,FALSE);        // put up the screen
  2670.  
  2671.         BroadcastToList (DRAWIT,CurrList);// draw the controls
  2672.  
  2673.         (*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
  2674.  
  2675.     // return good
  2676.  
  2677.         return (0);
  2678. }
  2679.  
  2680.  
  2681.     /*\
  2682.     |*|----====< int VolumeButtons() >====----
  2683.     |*|
  2684.     |*| Volume slide bar object control
  2685.     |*|
  2686.     |*| Entry Conditions:
  2687.     |*|     None
  2688.     |*|
  2689.     |*| Exit Conditions:
  2690.     |*|     None
  2691.     |*|
  2692.     \*/
  2693. static int VolumeButtons (msg,o,ptr)
  2694.     int msg;
  2695.     BPtr o;
  2696.     void *ptr;
  2697. {
  2698. void **pptr;
  2699. rect r;
  2700. int l,ri,i;
  2701. char c1,c2;
  2702.  
  2703.     // get a pointer to the stack
  2704.  
  2705.         pptr = &ptr;
  2706.  
  2707.     // process the message
  2708.  
  2709.         switch (msg) {
  2710.  
  2711.             case OPEVENT:
  2712.  
  2713.                 switch (((EPtr)pptr[0])->buttons) {
  2714.  
  2715.                     case ENTER:
  2716.  
  2717.                         if (o->state)
  2718.                             o->state = 0;
  2719.                         else
  2720.                             o->state = -1;
  2721.  
  2722.                         SendVolume
  2723.                           (
  2724.                             "SET ",
  2725.                             0,
  2726.                             (VPtr) o,
  2727.                             BI_SETTO,
  2728.                             o->state
  2729.                           );
  2730.  
  2731.                         (*o->scr) (DRAWIT,o);
  2732.  
  2733.                         break;
  2734.  
  2735.                     case ENDKEY:
  2736.                     case HOMEKEY:
  2737.                     case LFARROW:
  2738.                     case PGDNKEY:
  2739.                     case PGUPKEY:
  2740.                     case RIARROW:
  2741.  
  2742.                         // Direction keys can move these sliders
  2743.  
  2744.                         if (o == &Loudness)
  2745.                             (*BassVolume.scr)(msg,&BassVolume,ptr);
  2746.  
  2747.                         if (o == &Enhanced)
  2748.                             (*TrebVolume.scr)(msg,&TrebVolume,ptr);
  2749.                         break;
  2750.  
  2751.                     default:
  2752.                         break;
  2753.                 }
  2754.  
  2755.                 break;
  2756.  
  2757.             case SENDIT:
  2758.  
  2759.                 SendVolume
  2760.                   (
  2761.                     "SET ",
  2762.                     0,
  2763.                     (VPtr) o,
  2764.                     BI_SETTO,
  2765.                     o->state
  2766.                   );
  2767.                 (*(void(*)())ptr)(&CommandString);
  2768.  
  2769.                 break;
  2770.  
  2771.             case FOCUS_GIVEN:
  2772.  
  2773.                 // highlight the entire field
  2774.  
  2775.                     r.row1 = o->namr.row1;
  2776.                     r.row2 = o->namr.row2;
  2777.                     r.col2 = r.col1 = o->namr.col2+2;
  2778.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  2779.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  2780.  
  2781.                 //    r.row1 = o->scrr.row1;
  2782.                 //    r.row2 = o->scrr.row2;
  2783.                 //    r.col2 = r.col1 = o->scrr.col2+2;
  2784.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  2785.                 //    _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  2786.  
  2787.                     break;
  2788.  
  2789.             case FOCUS_TAKEN:
  2790.  
  2791.                 // highlight the entire field
  2792.  
  2793.                     r.row1 = o->namr.row1;
  2794.                     r.row2 = o->namr.row2;
  2795.                     r.col2 = r.col1 = o->namr.col2+2;
  2796.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  2797.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  2798.  
  2799.                 //    r.row1 = o->scrr.row1;
  2800.                 //    r.row2 = o->scrr.row2;
  2801.                 //    r.col2 = r.col1 = o->scrr.col2+2;
  2802.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  2803.                 //    _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  2804.  
  2805.                     break;
  2806.  
  2807.             case DRAWIT:
  2808.  
  2809.                 // move the cursor to the slide bar area
  2810.  
  2811.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  2812.                     if (o->state)
  2813.                         _zipout   ( "X" );
  2814.                     else
  2815.                         _zipout   ( "˘" );
  2816.  
  2817.                 break;
  2818.  
  2819.             case OPENINIT:
  2820.  
  2821.                 // get the output mixer current state
  2822.  
  2823.                     SendVolume ("GET ",0,(VPtr)o,0,0);
  2824.  
  2825.                     DecodeVolumeSwitch (MVResponse);
  2826.                     o->state = (VolumeSwitch == '+') ? -1 : 0;
  2827.                     break;
  2828.  
  2829.  
  2830.             case CLEARIT:
  2831.             default:
  2832.                 break;
  2833.         }
  2834. }
  2835.  
  2836.  
  2837.     /*\
  2838.     |*|----====< int UpdateTotalVolume() >====----
  2839.     |*|
  2840.     |*| update the screen if the user is typing the hot keys
  2841.     |*|
  2842.     |*| Entry Conditions:
  2843.     |*|     None
  2844.     |*|
  2845.     |*| Exit Conditions:
  2846.     |*|     None
  2847.     |*|
  2848.     \*/
  2849. static int UpdateTotalVolume()
  2850. {
  2851. int lv,rv;
  2852.  
  2853. static int delta;
  2854. static int mintic    = 18;
  2855. static int minrest    = 0;
  2856. //static int lasttime = 0;
  2857.  
  2858.     // get the clock tic, this whole routine is done once a second
  2859.  
  2860.         delta += _dlggettimedelta();    // the below code is now in dialoga.asm
  2861.         //    _asm {
  2862.         //        mov ah,0
  2863.         //        int 1Ah
  2864.         //        cmp lasttime,dx     ; ax = delta of current/last time
  2865.         //        mov lasttime,dx
  2866.         //        adc delta,0
  2867.         //    }
  2868.  
  2869.     // if the main dialog box is covered, we cannot draw, so just return
  2870.  
  2871.         if (DialogBox & EFFECTS_DLG)
  2872.             return(0);
  2873.  
  2874.     // if the change is greater than 1 second, update the screen now...
  2875.  
  2876.         if (delta > mintic) {
  2877.  
  2878.             delta    = 0;
  2879.  
  2880.             lv = LeftVolumeLevel.channel;
  2881.             rv = RitVolumeLevel.channel;
  2882.  
  2883.             (*LeftVolumeLevel.scr)(OPENINIT,&LeftVolumeLevel);
  2884.  
  2885.             if((lv != LeftVolumeLevel.channel) ||
  2886.                (rv != RitVolumeLevel.channel)) {
  2887.                     minrest = (1*19)/4;         // restore speed after 1 second
  2888.                     mintic    = 2;                // speed up polling
  2889.                     (*LeftVolumeLevel.scr)(DRAWIT,&LeftVolumeLevel);
  2890.             }
  2891.  
  2892.             if (minrest)                        // if fast poll
  2893.                 if (!--minrest)                 // check to see if we should
  2894.                     mintic = 18;                // slow it down.
  2895.         }
  2896. }
  2897.  
  2898.  
  2899.     /*\
  2900.     |*|----====< int VolumeLevels() >====----
  2901.     |*|
  2902.     |*| VOLUME LEFT/RIGHT control
  2903.     |*|
  2904.     |*| Entry Conditions:
  2905.     |*|     None
  2906.     |*|
  2907.     |*| Exit Conditions:
  2908.     |*|     None
  2909.     |*|
  2910.     \*/
  2911. static int VolumeLevels(msg,o,ptr)
  2912.     int msg;
  2913.     VPtr o;
  2914.     void *ptr;
  2915. {
  2916. void **pptr;
  2917. rect r;
  2918. int l,ri,i;
  2919. char c1,c2;
  2920.  
  2921. #define VOLE_RAMPUP 0x4001        // ramp the volume up
  2922. #define VOLE_RAMPDN 0x4002        // ramp the volume down
  2923.  
  2924.     // get a pointer to the stack
  2925.  
  2926.         pptr = &ptr;
  2927.  
  2928.     // process the message
  2929.  
  2930.         switch (msg) {
  2931.  
  2932.             case OPEVENT:
  2933.  
  2934.                 switch (((EPtr)pptr[0])->buttons) {
  2935.  
  2936.                     case ENDKEY:
  2937.                         VolumeLevels (VOLE_RAMPUP,&RitVolumeLevel,ptr);
  2938.                         break;
  2939.  
  2940.                     case HOMEKEY:
  2941.                         VolumeLevels (VOLE_RAMPUP,&LeftVolumeLevel,ptr);
  2942.                         break;
  2943.  
  2944.                     case LFARROW:
  2945.                         VolumeLevels (VOLE_RAMPUP,&LeftVolumeLevel,ptr);
  2946.                         VolumeLevels (VOLE_RAMPUP,&RitVolumeLevel,ptr);
  2947.                         break;
  2948.  
  2949.                     case PGDNKEY:
  2950.                         VolumeLevels (VOLE_RAMPDN,&RitVolumeLevel,ptr);
  2951.                         break;
  2952.  
  2953.                     case PGUPKEY:
  2954.                         VolumeLevels (VOLE_RAMPDN,&LeftVolumeLevel,ptr);
  2955.                         break;
  2956.  
  2957.                     case RIARROW:
  2958.                         VolumeLevels (VOLE_RAMPDN,&LeftVolumeLevel,ptr);
  2959.                         VolumeLevels (VOLE_RAMPDN,&RitVolumeLevel,ptr);
  2960.                         break;
  2961.  
  2962.                     default:
  2963.                         break;
  2964.                 }
  2965.  
  2966.                 break;
  2967.  
  2968.             case SENDIT:
  2969.  
  2970.                 SendVolume                    // set the left
  2971.                   (
  2972.                     "SET ",
  2973.                     1,
  2974.                     &LeftVolumeLevel,
  2975.                     BI_SETTO,
  2976.                     LeftVolumeLevel.channel
  2977.                   );
  2978.                 (*(void(*)())ptr)(&CommandString);
  2979.  
  2980.                 SendVolume                    // set the right
  2981.                   (
  2982.                     "SET ",
  2983.                     2,
  2984.                     &RitVolumeLevel,
  2985.                     BI_SETTO,
  2986.                     RitVolumeLevel.channel
  2987.                   );
  2988.  
  2989.                 (*(void(*)())ptr)(&CommandString);
  2990.  
  2991.                 break;
  2992.  
  2993.             case FOCUS_GIVEN:
  2994.  
  2995.                 // highlight the entire field
  2996.  
  2997.                     r.row1 = o->namr.row1;
  2998.                     r.row2 = o->namr.row2;
  2999.                     r.col2 = r.col1 = o->namr.col2+2;
  3000.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &o->namr );
  3001.                     _videoattr ( Colors->TmpHi_AND,    Colors->TmpHi_XOR,     &r       );
  3002.  
  3003.                     r.row1 = o->scrr.row1;
  3004.                     r.row2 = o->scrr.row2;
  3005.                     r.col2 = r.col1 = o->scrr.col2+2;
  3006.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
  3007.                     _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r       );
  3008.  
  3009.                 // let the right channel know too!
  3010.  
  3011.                     if (o == &LeftVolumeLevel)
  3012.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3013.  
  3014.                     break;
  3015.  
  3016.             case FOCUS_TAKEN:
  3017.  
  3018.                 // highlight the entire field
  3019.  
  3020.                     r.row1 = o->namr.row1;
  3021.                     r.row2 = o->namr.row2;
  3022.                     r.col2 = r.col1 = o->namr.col2+2;
  3023.                     _videoattr ( Colors->TmpLo_AND,    Colors->TmpLo_XOR,     &o->namr );
  3024.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  3025.  
  3026.                     r.row1 = o->scrr.row1;
  3027.                     r.row2 = o->scrr.row2;
  3028.                     r.col2 = r.col1 = o->scrr.col2+2;
  3029.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
  3030.                     _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r       );
  3031.  
  3032.                 // let the right channel know too!
  3033.  
  3034.                     if (o == &LeftVolumeLevel)
  3035.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3036.  
  3037.                     break;
  3038.  
  3039.             case DRAWIT:
  3040.  
  3041.                 // move the cursor to the slide bar area
  3042.  
  3043.                     _videosetcurs ( o->scrr.row1, o->scrr.col1 );
  3044.                     _zipout       ( twobar, 0);
  3045.  
  3046.                     l = (o->channel * 31) / 100;
  3047.                     _videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
  3048.                     _zipout (((l & 1) ? "fi" : "›"), 0);
  3049.  
  3050.                 // let the right channel know too!
  3051.  
  3052.                     if (o == &LeftVolumeLevel)
  3053.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3054.  
  3055.                 break;
  3056.  
  3057.             case OPENINIT:
  3058.  
  3059.                 // get the output mixer current state
  3060.  
  3061.                     SendVolume
  3062.                       (
  3063.                         "GET ",
  3064.                         ((o == &LeftVolumeLevel) ? 1 : 2),
  3065.                         o,
  3066.                         0,
  3067.                         0
  3068.                       );
  3069.  
  3070.                     DecodeVolumeNumber (MVResponse);
  3071.                     o->channel = VolumeNumber;
  3072.  
  3073.                 // let the right channel know too!
  3074.  
  3075.                     if (o == &LeftVolumeLevel)
  3076.                         (*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
  3077.  
  3078.                     break;
  3079.  
  3080.             case CLEARIT:
  3081.                 break;
  3082.  
  3083.             case VOLE_RAMPUP:
  3084.  
  3085.                 // send the volume up
  3086.  
  3087.                     if (o->channel > 0)
  3088.                         o->channel -= 4;
  3089.  
  3090.                     SendVolume                    // set left/both/right
  3091.                       (
  3092.                         "SET ",
  3093.                         ((o == &LeftVolumeLevel) ? 1 : 2),
  3094.                         o,
  3095.                         BI_SETTO,
  3096.                         o->channel
  3097.                     );
  3098.  
  3099.                     (*o->scr) (DRAWIT,o);        // redraw it
  3100.  
  3101.                     break;
  3102.  
  3103.             case VOLE_RAMPDN:
  3104.  
  3105.                 // send the volume down
  3106.  
  3107.                     if (o->channel < 100)
  3108.                         o->channel += 4;
  3109.  
  3110.                     SendVolume
  3111.                       (
  3112.                         "SET ",
  3113.                         ((o == &LeftVolumeLevel) ? 1 : 2),
  3114.                         o,
  3115.                         BI_SETTO,
  3116.                         o->channel
  3117.                       );
  3118.  
  3119.                     (*o->scr) (DRAWIT,o);
  3120.  
  3121.                     break;
  3122.  
  3123.             default:
  3124.                 break;
  3125.         }
  3126. }
  3127.  
  3128.  
  3129. ;    /*\
  3130. ;---|*|----====< clrbuf() >====----
  3131. ;---|*|
  3132. ;---|*| zero out a buffer
  3133. ;---|*|
  3134. ;    \*/
  3135.  
  3136. clrbuf(char *buf, int size)
  3137. {
  3138.     int s;
  3139.  
  3140.     for (s= 0; s < size; s++)
  3141.         *buf++= '\0';
  3142. }
  3143.  
  3144.  
  3145. ;    /*\
  3146. ;---|*|----====< dissolve() >====----
  3147. ;---|*|
  3148. ;---|*| Take a buffer, and write it to the screen in a random fashion
  3149. ;---|*|
  3150. ;    \*/
  3151.  
  3152. dissolve(h,width,buff)
  3153.     int h;
  3154.     int width;
  3155.     char far *buff;
  3156. {
  3157. int pixels,lastnum;
  3158. int regwidth;
  3159. long mask;
  3160. unsigned long seq;
  3161. int row, col;
  3162.  
  3163.     // find the smallest "register" that produces enough pixel numbers
  3164.  
  3165.     pixels     = h * width;
  3166.  
  3167.     lastnum  = pixels -1;
  3168.  
  3169.     mask = 0x500;
  3170.  
  3171.     seq = 1;
  3172.  
  3173.     do {
  3174.  
  3175.         row = seq / width;
  3176.  
  3177.         col = seq % width;
  3178.  
  3179.         if (row < h)
  3180.             plug (row,col,buff);
  3181.  
  3182.         // compute the next element
  3183.  
  3184.         if (seq & 1) {
  3185.  
  3186.             _asm {
  3187.                 mov     ax,word ptr [seq]
  3188.                 shr     ax,1
  3189.                 xor     ax,word ptr [mask]
  3190.                 mov     word ptr [seq],ax
  3191.             }
  3192.  
  3193.             //seq = (seq >> 1) ~ mask;
  3194.         }
  3195.  
  3196.         else
  3197.  
  3198.             seq >>= 1;
  3199.  
  3200.     } while (seq != 1);
  3201.  
  3202.     plug (0,0,buff);
  3203. }
  3204.  
  3205.  
  3206. plug(row,col,buff)
  3207.     int row;
  3208.     int col;
  3209.     char far *buff;
  3210. {
  3211.  
  3212.     _asm {
  3213.  
  3214.         push    es
  3215.         push    si
  3216.  
  3217.         mov     ax,[row]
  3218.         mov     si,160
  3219.         mul     si
  3220.         add     ax,[col]
  3221.         add     ax,[col]
  3222.         mov     si,ax
  3223.  
  3224.         les     bx,[buff]
  3225.         mov     ax,es:[bx+si]
  3226.  
  3227.         mov     es,[VideoSegment]
  3228.         mov     es:[si],ax
  3229.  
  3230.         mov     dx,250h
  3231.         mov     cx,30h
  3232.  
  3233.     } xyz: _asm {
  3234.  
  3235.         in      al,dx
  3236.         loop    xyz
  3237.  
  3238.         pop     es
  3239.     }
  3240. }
  3241.  
  3242.  
  3243.  
  3244. /* filename is catted onto driver pathname, and the "s." is changed to "#." */
  3245. /* where "#" is from 0 to 3, allowing 4 different mixer settings to be saved. */
  3246.  
  3247. char *filename= "settings.pas";
  3248.  
  3249. /* getdriverpath() - use int 2F function BC0B to get path to mvsound.sys */
  3250. /* return !0 and fill "pathname" buffer with path to driver if successful */
  3251. /* return 0 if failed */
  3252.  
  3253. getdriverpath(char far *pathname)
  3254. {
  3255.     int status;
  3256.     char far *p= pathname;
  3257.  
  3258.     _asm {
  3259.         mov ax, 0BC0Bh
  3260.         int 2Fh
  3261.  
  3262.         xor ax, 'M' SHL 8 + 'V'
  3263.         mov status, ax
  3264.         jnz sorry
  3265.  
  3266.         push ds
  3267.         push es
  3268.         push si
  3269.         push di
  3270.  
  3271.         mov di, word ptr p[2]
  3272.         mov es, di
  3273.         mov di, word ptr p[0]
  3274.         mov ds, dx
  3275.         mov si, bx
  3276.  
  3277.         mov cx, 79
  3278.  
  3279.     } again: _asm {
  3280.  
  3281.         lodsb
  3282.         stosb
  3283.         or al, al
  3284.         jz done
  3285.         loop again
  3286.  
  3287.         jmp short done
  3288.  
  3289.     } done: _asm {
  3290.  
  3291.         sub cx, 77
  3292.         jnz notroot
  3293.         mov bx,-1
  3294.         mov byte ptr es:[di], 0
  3295.         dec di
  3296.         mov byte ptr es:[di], 05ch
  3297.  
  3298.     } notroot: _asm {
  3299.  
  3300.         pop di
  3301.         pop si
  3302.         pop es
  3303.         pop ds
  3304.  
  3305.     } sorry:
  3306.  
  3307.     return(!status);
  3308. }
  3309.  
  3310. /* evaluate the "##   +/-   ##   +/-" string */
  3311. /* the first "## +/-" pair is the left channel, the second is the right */
  3312. /* set up four pointers to point to each of the four elements */
  3313. /* passed in is "channel", either 'L' or 'R', and "onoroff", either "+" or "-" */
  3314. /* if the L/R "onoroff" matches the passed "onoroff", return the L/R val */
  3315.  
  3316. char *isonoroff(char channel, char onoroff)
  3317. {
  3318.     char *lfvalue, *lfonoff, *rtvalue, *rtonoff;
  3319.     char *val, *oo;
  3320.  
  3321.     /* MVResponse= "LeftVal   LeftOnOff   RightVal   RightOnOff" */
  3322.     lfvalue= MVResponse;
  3323.     while (isspace(*lfvalue)) lfvalue++;
  3324.  
  3325.     lfonoff= lfvalue;
  3326.     while (!isspace(*lfonoff)) lfonoff++;
  3327.     while (isspace(*lfonoff)) lfonoff++;
  3328.  
  3329.     rtvalue= lfonoff;
  3330.     while (!isspace(*rtvalue)) rtvalue++;
  3331.     while (isspace(*rtvalue)) rtvalue++;
  3332.  
  3333.     rtonoff= rtvalue;
  3334.     while (!isspace(*rtonoff)) rtonoff++;
  3335.     while (isspace(*rtonoff)) rtonoff++;
  3336.  
  3337.     /* select val and oo according to Left or Right channel */
  3338.     switch (channel)
  3339.         {
  3340.         case 'l':
  3341.         case 'L': val= lfvalue; oo= lfonoff; break;
  3342.         case 'r':
  3343.         case 'R': val= rtvalue; oo= rtonoff; break;
  3344.         default: val= NULL; oo= NULL; break;
  3345.         }
  3346.  
  3347.     if (*oo == onoroff)
  3348.         return(val);
  3349.  
  3350.     return(NULL);
  3351.  
  3352. }
  3353.  
  3354. /* put an ascii number for "num" into the character left of the "." */
  3355. /* from the end of the string, search backwards to the first "." */
  3356. /* if not at the start of the string, stuff the ascii number */
  3357.  
  3358. putnuminname(char *pathname, int num)
  3359. {
  3360.     int i= strlen(pathname);
  3361.     while (i && pathname[i] != '.')
  3362.         i--;
  3363.     if (i)
  3364.         pathname[--i]= num+ '0';
  3365. }
  3366.  
  3367. /* get the driver path, stuff the number into the name, and create the file */
  3368. /* save the master L/R volume, the "dead" then the "live" mixer settings */
  3369. /* the bass, treble and enhanced status, the realsound setting, and the */
  3370. /* crosschannel settings */
  3371. /* These are saved as strings in a DOS file suitable for "cat FILE > mvproas" */
  3372. /* which is what the "loadcurrent()" function does */
  3373. /* The filename is "X:\driver\path\setting#.pas", where "#" is 0-3, allowing */
  3374. /* four different settings to be maintained */
  3375.  
  3376. #define USEMIXERGET 1
  3377.  
  3378. FILE *fout;
  3379.  
  3380. subsavecurrent(char *cmdstring)
  3381. {
  3382.     if (*cmdstring)
  3383.         {
  3384.         fprintf(fout, "%s\n", cmdstring);
  3385.         }
  3386.  
  3387.     return(0);
  3388. }
  3389.  
  3390. savecurrent(int num)
  3391. {
  3392.     char pathname[128];
  3393.  
  3394.     if (!getdriverpath(pathname))
  3395.         return(0);
  3396.  
  3397.     if (strlen(pathname) > 3)
  3398.         strcat(pathname, "\\");
  3399.     strcat(pathname, filename);
  3400.     putnuminname(pathname, num);
  3401.  
  3402.     fout= fopen(pathname, "w");
  3403.     if (fout == NULL)
  3404.           return(0);
  3405.  
  3406.     MixerGetSettings(subsavecurrent);
  3407.  
  3408.     fclose(fout);
  3409.  
  3410.     return(0);
  3411. }
  3412.  
  3413. /* load setting #num from file "setting#.pas" */
  3414. /* open the file, read each line and send it to mvproas */
  3415. /* if the file does not exist, save the current settings and then proceed */
  3416. /* The file contains mvproas strings, so "cat setting#.pas > mvproas" works */
  3417.  
  3418. loadcurrent(int num)
  3419. {
  3420.     int okay;
  3421.     FILE *finp;
  3422.     char pathname[128];
  3423.     char cmdstring[128];
  3424.  
  3425.     if (!getdriverpath(pathname))
  3426.         return(0);
  3427.  
  3428.     if (strlen(pathname) > 3)
  3429.         strcat(pathname, "\\");
  3430.     strcat(pathname, filename);
  3431.     putnuminname(pathname, num);
  3432.  
  3433.     finp= fopen(pathname, "r");
  3434.     if (finp == NULL)
  3435.         {
  3436.         savecurrent(num);
  3437.         finp= fopen(pathname, "r");
  3438.         if (finp == NULL)
  3439.             return(0);
  3440.         }
  3441.  
  3442.     while ((fgets(cmdstring, 127, finp)) != NULL)
  3443.         SendTextOut(cmdstring);
  3444.  
  3445.     fclose(finp);
  3446.  
  3447. }
  3448.  
  3449. /*The GET commands and parameters are:
  3450.        GET {LEFT or RIGHT} [FM     ]
  3451.        GET {LEFT or RIGHT} [PCM    ]
  3452.        GET {LEFT or RIGHT} [INT    ]
  3453.        GET {LEFT or RIGHT} [EXT    ]
  3454.        GET {LEFT or RIGHT} [SPEAKER]
  3455.        GET {LEFT or RIGHT} [MIC    ]
  3456.        GET [BASS]                   
  3457.        GET [TREBLE]                 
  3458.        GET {LEFT or RIGHT} [VOLUME ]
  3459.        GET [MUTE]
  3460.        GET [ENHANCED]
  3461.        GET [REALSOUND]
  3462.        GET [CROSSCHANNEL]
  3463. The following demonstrates several ways to GET volume, button, or mixer levels:
  3464.        GET FM
  3465.        GET VOLUME
  3466.        GET MUTE
  3467.        GET CROSSCHANNEL
  3468.        GET REAL
  3469. */
  3470.  
  3471. unlinkTBScroll()
  3472. {
  3473.     Scroll *n= (Scroll *) TBScroll.next;
  3474.     Scroll *b= (Scroll *) TBScroll.back;
  3475.  
  3476.     n->back= b;
  3477.     b->next= n;
  3478.  
  3479.     screen3[15]= screen3blank[0];
  3480.     screen3[16]= screen3blank[1];
  3481.     screen3[17]= screen3blank[2];
  3482.  
  3483.     screenlayout[17]= screenlayoutblank[0];
  3484.     screenlayout[18]= screenlayoutblank[1];
  3485.     screenlayout[19]= screenlayoutblank[2];
  3486.  
  3487.     screenlayout[15][2]= 'P';
  3488.     screenlayout[15][3]= 'C';
  3489.     screenlayout[15][4]= ' ';
  3490.     screenlayout[15][5]= 'S';
  3491.     screenlayout[15][6]= 'p';
  3492.     screenlayout[15][7]= 'e';
  3493.     screenlayout[15][8]= 'a';
  3494.     screenlayout[15][9]= 'k';
  3495.     screenlayout[15][10]='e';
  3496.     screenlayout[15][11]='r';
  3497.  
  3498.     screenlayout[16][2]= 'S';
  3499.     screenlayout[16][3]= 'B';
  3500.     screenlayout[16][4]= ' ';
  3501.     screenlayout[16][5]= 'V';
  3502.     screenlayout[16][6]= 'o';
  3503.     screenlayout[16][7]= 'l';
  3504.     screenlayout[16][8]= 'u';
  3505.     screenlayout[16][9]= 'm';
  3506.     screenlayout[16][10]='e';
  3507.     screenlayout[16][11]=' ';
  3508.  
  3509.  
  3510. }
  3511.  
  3512. ;    /*\
  3513. ;---|*| end DIALOG.C
  3514. ;    \*/
  3515.  
  3516.  
  3517.